GraphQLを使う上で、GraphQL Code Generatorというツールがとても便利で、色々なコードを生成してくれるというのは知っていました。
実際、普段は設定されていたのものを使っているのですが、改めてどんなツールなのかをちゃんと理解していないなと思い、調べてみました。
GraphQL Schema
GraphQL Code Generatorがコードを生成するベースとなるのはGraphQL Schemaです。
フロントエンドでTypeScriptを使っていると、一見TypeScriptにも見えてしまうのですが、これはGraphQL schema languageです。
type Human implements Character {
id: ID!
name: String!
friends: [Character]
appearsIn: [Episode]!
starships: [Starship]
totalCredits: Int
}
GraphQL Schemaは言語に依存しない独自のシンタックスのため、GraphQLサーバーの実装言語を特定のものに制限しません。
今回説明するクライアント側のコードは、このスキーマがベースとなって生成されます。
クライアント側のコード生成
GraphQL Code GeneratorではPluginを使うことで様々なコードを生成することができます。
今回はクライアント側でよく使いそうなものをいくつか紹介していきます。
事前準備
デモとしてSchemaが必要なので、GitHub GraphQL APIのスキーマを使用します。
以下のページからダウンロードできるので、ダウンロードしてリポジトリに配置します。
ちなみに、今回私がいじってみた環境はこちらです。
@graphql-codegen/cli: v2.6.2
1. GraphQL Schemaの型定義
GraphQL Schemaを元に、クライアント側で使う型定義ファイルを生成します。
pluginはTypeScript
を使用します。
以下のようにcodegen.ymlを設定すると、src/generated/types.ts
にGitHub GraphQL APIのスキーマを元に型定義が生成されます。
overwrite: true
schema: './github.schema.graphql'
documents: 'src/graphql/*.gql'
generates:
src/generated/types.ts:
plugins:
- typescript
中身を見てみると、オブジェクトの型や、スカラー、enum、クエリの引数などの型が生成されていました。
詳しくはこちらに生成したファイルを置いているので、見てみてください。
2. オペレーションの型
これは、クライアント側で定義したquery, mutation, subscription, fragmentの型です。
TypeScript Operations
を使います。
例えば、以下のようなクエリを定義しておきます。
query GetViewer {
viewer {
login
}
}
そして設定を追加してコードを生成してみると以下のようになりました。
export type GetViewerQueryVariables = Types.Exact<{ [key: string]: never }>
export type GetViewerQuery = {
__typename?: 'Query'
viewer: { __typename?: 'User'; login: string }
}
今回のQueryには引数が無いこと、Queryを実行した時に上記のような型でデータが帰ってくることが分かります。
これを使うことで型安全なコードが実装できそうです。
3. React hooksの生成
TypeScript React Apollo
を使うとhooksを生成することもできます。
import { useQuery } from '@apollo/client'
import type { GetViewerQuery } from './generated/operations'
import GetViewer from './graphql/GetViewer.gql'
const { data } = useQuery<GetViewerQuery>(GetViewer)
1, 2までで生成したコードを使って上記のようにしても良いのですが、このpluginを使うとuseGetViewerQuery
というhooksが作られ、
import { useGetViewerQuery } from './generated/graphql'
const { data } = useGetViewerQuery()
上記のコードだけで済むので記述量を減らすことができます。
実装は単純にuseQuery
をラップしたもののようでした。
export function useGetViewerQuery(
baseOptions?: Apollo.QueryHookOptions<
Types.GetViewerQuery,
Types.GetViewerQueryVariables
>
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useQuery<Types.GetViewerQuery, Types.GetViewerQueryVariables>(
GetViewerDocument,
options
);
}
(補足: 調べていく中で、以下のような記事もあったので、使用を絶対おすすめするというものではありません)
これも今後使ってみようと思います。
その他
その他にも様々なpluginがあります。
今回紹介したのはクライアント用でしたが、バックエンド用や、React以外のライブラリ用のpluginもあります。
また、GraphQL Code GeneratorのサイトトップにはLive Exampleがあり、具体的にどんなコードが生成されるのかイメージしやすいものもあるので、ぜひ見てみてください。
今回見きれなかった部分もあるので、もっと色々触ってみようと思います!