GraphQL Code GeneratorでGraphQlのschemaからTypescriptの型定義を生成する方法
GraphQL Code Generatorとは
GraphQLでAPIを作る際に、バックエンド側では、GraphQLのschemaとresolverを書くことになります。
もし、Typescriptでresolverのコードを書いていた場合、型定義の内容が、schemaで書いた内容と似通っていて、二度手間になっているように思えてきます。
また、schemaと型定義でのデータ型に不整合があると、エラーの原因になります。
GraphQL Code Generatorは、この問題を解消できる便利なnodejsライブラリです。
この使い方を単純なサンプルと併せて紹介します。
使用するschemaとresolverの例
schemaの例として以下のようなユーザー一覧を出すものを考えてみます。
src/typedefs/users.gql
ファイルには、
1 2 3 4 5 6 7 8 9 10 | type User { id: Int name: String } type Query { listUsers(offset: Int, limit: Int): [User] } |
これに対応するresolverとして、
src/resolvers/users.ts
ファイルに以下のようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | export const usersResolvers = { Query: { listUsers (_parent, args) { if (args.offset && args.limit) { const users = [...mockdata.users].slice(args.offset, args.offset + args.limit) return users } else { return mockdata.users } }, }, }; |
このように、schemaとresolverを定義する例を考えます。
上記の例で、もしeslintなどを有効にしていると、
args
に型付されていないというエラーが表示されるはずです。手作業で型定義するとどうなるか
上記のエラーを解消するために、
listUsersArgs
ような型定義を導入すると、以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | interface listUsersArgs { offset: number limit: number } export const usersResolvers = { Query: { listUsers (_parent, args: listUsersArgs) { if (args.offset && args.limit) { const users = [...mockdata.users].slice(args.offset, args.offset + args.limit) return users } else { return mockdata.users } }, }, }; |
同様にして、戻り値などへの型定義も追記していくことになります。
ここで、
listUsersArgs
のoffset
やlimit
のデータ型は、schemaのlistUsers(offset: Int, limit: Int): [User]
という部分を見れば、明確な対応関係にあるとわかります。そのため、
listUsersArgs
のような型定義をわざわざ書くのはバグの温床です。GraphQL Code Generatorのインストールと設定
GraphQL Code Generatorを使うには、CLIツールと、必要に応じた各種プラグインのインストールが必要になります。
今回のようにTypescriptでのresolverの型定義を生成する場合は、以下のライブラリのインストールで十分です。
1 | npm install --save-dev @graphql-codegen/cli @graphql-codegen/introspection @graphql-codegen/typescript @graphql-codegen/typescript-operations @graphql-codegen/typescript-resolvers |
続いて、GraphQL Code Generatorの設定ファイル用意します。
codegen.yml
ファイルに以下のように書きます。
1 2 3 4 5 6 7 8 9 10 11 12 | overwrite: true schema: src/typedefs/*gql generates: src/generated/graphql.ts: plugins: - "typescript" - "typescript-resolvers" ./graphql.schema.json: plugins: - "introspection" |
これで、
src/typedefs/*gql
で指定されたパスのschemaファイルを読みとって、自動生成した型定義をsrc/generated/graphql.ts
に書き出します。GraphQL Code Generatorの実行結果
設定を済ませてから、
npm run graphql-codegen
とすると、graphql.ts
が生成されます。その内容の一部を抜粋すると、以下のようになります。
1 2 3 4 5 6 | export type Resolvers = { Query?: QueryResolvers; User?: UserResolvers; }; |
これをそのまま、importして、resolverの型付けに使用すると、以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import type { Resolvers } from "../generated/graphql" export const usersResolvers: Resolvers = { Query: { listUsers (_parent, args) { if (args.offset && args.limit) { const users = [...mockdata.users].slice(args.offset, args.offset + args.limit) return users } else { return mockdata.users } }, }, }; |
eslintの”型付されていない”というエラーも解消されていることがわかります。
このように、resolverの型が作られていて、自分で定義する必要がなくなりました。
まとめ
graphQLのshemaからTypescript用の型定義を自動生成するGraphQL Code Generatorの使い方を紹介しました。
graphQLでAPI開発をしていて、作業効率を上げたい方におすすめです。
Author Profile
スターフィールド編集部
SHARE