開発中に使って開発体験がよかったので忘備録みたいな感じでまとめます。
開発環境
react v19.2
graphql-codegen/cli v6.1.0
graphql-codegen/typescript v5.0.6
graphql-codegen/typescript-operations v5.0.6
graphql-codegen/typescript-react-apollo v4.3.3
GraphQL Code Generaterとは
- GraphQLスキーマからコードを生成するツール
- 型やカスタムフックを生成できる
- フロントエンドで使う
インストール
npm install -D @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-operations @graphql-codegen/typescript-react-apollo
それぞれの役割
-
graphql-codegen/cli
codegen.tsやcodegen.ymlなどの設定ファイルを読み込むための -
graphql-codegen/typescript
バックエンドで定義したschemaを元にTypeScriptの型を生成 -
graphql-codegen/typescript-operations
クエリファイルを元にレスポンスの型を生成 -
graphql-codegen/typescript-react-apollo
graphql-codegen/typescript,
graphql-codegen/typescript-operations
で生成される方を元に、Reactのカスタムフックを生成
設定ファイル
私はフロントエンドのルート配下に置きました。
import type { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
overwrite: true, //生成ファイルの上書き設定
schema: 'http://localhost:5050/graphql', //スキーマファイルの読み込み
documents: 'src/**/*.graphql', //クエリファイルの読み込み
generates: {
'src/lib/graphql/generated/graphql.ts': { //生成ファイルのパス
plugins: [
'typescript',
'typescript-operations',
'typescript-react-apollo',
],
},
},
}
export default config;
バックエンドのschema準備
設定ファイルの
クエリファイルの準備
設定ファイルのdocumentsで定義した場所(今回は'src/**/*.graphql')にクエリファイルを作成します。
query GetUsers{ //getしたいときはquery
users{
id
name
email //必要なデータだけ書く
}
}
mutation CreateUser($name:String!,$email:String!){
createUser{
id
createdAt
}
}
コード生成
以下のコマンドを実行します。
npx graphql-codegen
すると設定ファイルのgeneratesで定義した場所(今回は'src/lib/graphql/generated/graphql.ts')
にコードが生成されます。
生成されるコード
主に下記のようなコードが大量に生成されます。(一部抜粋)
生成されたコードを使用するうえでコードを完璧に理解する必要はないかと思います。
カスタムフックも呼び出すだけで大丈夫なのですごく便利です。
スキーマを元にしたデータの原型の型
バックエンドのGraphQLスキーマ(type User等)がそのままTypeScriptの型として定義されています。
export type User = {
__typename?: 'User';
id: string;
name: string;
email: string;
createdAt: any;
};
実際に「取得するデータ」だけの型
自分で書いたクエリ(query GetUsers等)に対応する型が定義されています。
クエリで要求したフィールドしか型に含まれないです。
export type GetUsersQuery = {
__typename?: 'Query';
users: Array<{
__typename?: 'User';
id: string;
name: string;
}>;
};
カスタムフック
上記の型を使ってApolloClientを呼び出すための関数(Hooks)が定義されています。
import * as Apollo from '@apollo/client';
export const useGetUsersQuery = (
baseOptions?: Apollo.QueryHookOptions<GetUsersQuery, GetUsersQueryVariables>
) => {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useQuery<GetUsersQuery, GetUsersQueryVariables>(
GetUsersDocument,
options
);
};
コード生成の効果
GraphQL-Code-Generaterを利用していないコード
import { useQuery, gql } from '@apollo/client';
type User = { id: string; name: string };
type GetUsersData = { users: User[] };
const GET_USERS = gql`
query GetUsers {
users { id, name }
}
`;
export const UserList = () => {
const { data, loading } = useQuery<GetUsersData>(GET_USERS);
if (loading) return <p>Loading</p>;
return(
//map関数等
)
}
GraphQL-Code-Generaterを利用したコード
import { useGetUsersQuery } from '../lib/graphql/generated/graphql';
export const UserList = () => {
const { data, loading, error } = useGetUsersQuery();
if (loading) return <p>Loading</p>;
if (error) return <p>Error: {error.message}</p>;
return (
//map関数等
);
};
コード量が減り、非常にすっきりしました。
GraphQLを使用する機会があれば使ってみてください。
雑でしたが以上になります。ありがとうございました。