GraphQL Code Generator の使い方。〜GraphQLのSchemaからTSの型定義を自動生成する〜


TypeScript × GraphQLの開発で必須のライブラリ GraphQL Code Generator の紹介です。


![スクリーンショット 2020-04-04 13.55.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114396/b69e3a85-e388-2446-93f4-7aa0852df979.png)

https://graphql-code-generator.com/

# graphql codegenとは？

GraphQLのエンドポイントや、GraphQLのschema定義からTypeScriptの型定義を生成するCLIツールです。
しかも、生成するものはTypeScriptの型定義だけに限らず、Pluginを使うことでApolloクライアントのコードや、TypeScriptのリゾルバ、Javaのリゾルバまで様々なものを生成できます。

生成するもの一例

* TypeScriptの型定義 <= 今回説明
* TypeScriptのオペーレーションの型定義 <= 今回説明
* schema.graphqlファイル <= 今回説明
* vue-apolloのクライアントコード
* react-apolloのクライアントコード
* TypeScriptのリゾルバ
* Floq Type
* Javaのリゾルバ  
...などなど

# setup

プロジェクトのディレクトリで以下を実行してください。

```
npx graphql-codegen init
```

init時の選択内容に合わせてcodegen.ymlが生成されます。

最小の設定ファイルは以下の通りです。

```codegen.yaml
schema: エンドポイントのURL、schemaファイルパス
generates:
  生成したいファイルパス
    plugins:
      使用するプラグイン
```

# TypeScriptの型定義を生成

まず、基本のGraphQLのschemaからTypeScriptの型定義を生成する方法です。
codegen.yamlを以下のように設定します。

```yaml
schema: "https://example.com/v1/graphql"
generates:
  ./src/@types/types.d.ts:
    plugins:
      - typescript
```

そしてcli設定時に指定したnpmスクリプトを実行すると`./src/@types`に`types.d.ts`が生成されるはずです。

```bash
# init時に設定したnpmスクリプト名で実行
yarn codegen
```



# operationsの型定義の生成

schemaからの自動生成の型以外にも、プロダクトで使っているQuery, Mutationsからその操作専用の型を作ることもできます。
@graphql-codegen/typescript-operations を 追加して以下のようにcodegen.ymlを修正しましょう。

```bash
yarn add -D @graphql-codegen/typescript-operations 
```

```diff:codegen.yaml
  schema: "https://example.com/v1/graphql"
+ documents: src/graphql/**/*.ts
  generates:
    ./src/@types/types.d.ts:
      plugins:
        - typescript
+       - typescript-operations
```

この状態で`yarn codegen`を実行すると、以下の生成対象のオペレーション（Mutation）のから、

```addProduct.ts
export const ADD_PRODUCT = gql`
    mutation AddProduct($name: String!) {
        insert_products(objects: { name: $name }) {
            returning {
                id
                name
                created_at
            }
        }
    }
  `

```

Mutationの戻り値と、引数の型が自動生成されます。apolloクライアントを使う際の型指定などでそのまま使えます！

```type.d.ts
export type AddProductMutationVariables = {
  name: Scalars['String'];
};

export type AddProductMutation = (
  { __typename?: 'mutation_root' }
  & { insert_products?: Maybe<(
    { __typename?: 'products_mutation_response' }
    & { returning: Array<(
      { __typename?: 'products' }
      & Pick<Products, 'id' | 'name' | 'created_at'>
    )> }
  )> }
);

```




# schema.graphqlの生成

HASURAなどのGraphQLエンジンを使っていて、手元にschema.graphqlがない場合にはそちらも生成することが出来ます。

```
yarn add -D @graphql-codegen/schema-ast
```

```diff:codegen.yaml
  schema: "https://example.com/v1/graphql"
  documents: src/graphql/**/*.ts
  generates:
    ./src/@types/types.d.ts:
      plugins:
        - typescript
        - typescript-operations
+   ./schema.graphql:
+     plugins:
+       - schema-ast
```

この状態で`yarn codegen`を実行するとプロジェクトルートに`./schema.graphql`が生成されます。

schema.graphqlがあるとIntelliJのJS-GraphQLプラグインなどでコード補完が効くようになりとても便利です。

JS-GraphQLについては、[intelliJでgraphQLを書くときに便利なプラグイン ](https://qiita.com/ryo2132/items/b9bad0e1be756337482e) で紹介してます。


# 終わりに

GraphQLとTypeScriptに合わせてgraphql codegenを使うことで開発体験が大きく変わるな〜と思います。