問題
Typescriptを使ってgraphqlは型定義が煩雑になる
- graphqlのschemaで全て定義してるのに
- 使う側のTypescriptで再度同じ定義する必要がある(variablesだったり、戻り値のオブジェクト定義だったり)
これをendpointのschemaや、実際に使っているgraphqlクエリから型定義を自動生成しようというのが↓
GraphQL Codegen
必要になるもの
-
schema
- graphqlのendpoint(apollo-clientで接続するURL)
- GraphQL Introspection JSONでのschemaファイル
- schemaファイル
- のいずれか
-
使用する実際のgraphqlクエリファイル
- https://graphql-code-generator.com/docs/getting-started/documents-field
- (通常
const query = gql...
で定義するものをファイルへ書き出す必要がある) - 書き出さなくても、
documents: src/**/*.{ts,tsx}
のように設定してコード内のgraphqlクエリを読み出せるみたい - 実際には生成される
useHook
を使う事になり、そうなるとクエリをコード内に書く必要がなくなるので、どうしても最後には別ファイルにクエリを書き出す事になると思うが...
query UserInfo{
name
age
}
始め方
ドキュメントに沿ってやってみたが実際にはエラーで止まる箇所があるので、以下のように理解してやってみた。
まずは必要なパッケージのインストール
$ yarn add graphql
$ yarn add -D @graphql-codegen/cli
その後は次のコマンドでcodegen.yml
を自動生成できるが、これで自動生成されたものでは実際にはうまく動かないので、スキップ(v1.0.7現在)
$ graphql-codegen init # やらない
自分でcodegen.yml
を作る
overwrite: true # 出力するファイルを毎度上書きする
schema: "http://localhost:3000/graphql" # 自分のendpoint
documents: "**/*.graphql" # クエリファイル 拡張子は変えても良い
generates:
src/generated/graphql.ts: # 出力するファイル名
# 出力先、ファイル名は任意だが、拡張子はtsまたはtsx
plugins: # 必要となるプラグイン
- "typescript"
- "typescript-operations"
- "typescript-react-apollo"
config:
# 下の3つはtypescript-react-apolloのオプション
withHOC: false # HOCは要らないので
withComponent: false # falseなので出力ファイル拡張子が.tsでもいい。
# このオプションを設定しないとデフォルトtrueなので、.tsx拡張子にしろとエラーが出る
withHooks: true # 上のdocumentsの設定があればこれでhookが自動生成される
参考:
- https://graphql-code-generator.com/docs/getting-started/codegen-config
-
https://graphql-code-generator.com/docs/getting-started/schema-field
- URL
- GraphQL Introspection JSON https://graphql.org/learn/introspection/
- graphql schema ファイル https://graphql.org/learn/schema/
- https://graphql-code-generator.com/docs/getting-started/documents-field
- https://graphql-code-generator.com/docs/plugins/typescript
- https://graphql-code-generator.com/docs/plugins/typescript-operations
- https://graphql-code-generator.com/docs/plugins/typescript-react-apollo
pluginsに挙げたpackageはまだインストールしていないので、インストールする
yarn add -D @graphql-codegen/typescript @graphql-codegen/typescript-operations @graphql-codegen/typescript-react-apollo
codegen.yml
のdocuments
に書いたパスへクエリファイルを配置する
(このクエリファイルが無いとwithHooks:true
でもhookは出力されないので注意)
query UserInfo{
name
age
}
最後にyarn generate
と簡単に出来るようにscriptを追加
"scripts": {
"generate": "graphql-codegen --config codegen.yml"
}
そして実行
yarn generate
そうするとsrc/generated/graphql.ts
が出力される
これにより今までTypescript側でも行っていた型定義が不要になる(importすればいいだけになる)
さらにdocuments
に書いたクエリ毎のuseHook
も出来上がっているので、下のように簡単にgraphqlが使えるようになる
使用例
import { useGeneratedQuery } from "./src/generated/graphql"
...
...
export default () => {
const query = useGeneratedQuery()
if(query.loading){
return
}
return (
<div>{query.data.name}</div>
)
}
このhookに関してはデフォルト(hooksImportFrom (string, default value: react-apollo-hooks))としてreact-apollo-hooks
を使っているので、実際に使用する際には
$ yarn add react-apollo-hooks
が必要になる