【Next.js】GraphQL Code Generatorを使ってTypeScriptの型定義を自動化しよう！（GitHub GraphQL API）

APIデータを取得した際、取得したデータに対してまずは手動でTypeScriptの型定義を行うかと思いますが、**GraphQL Code Generator**を使うと自動でTypeScriptの型定義をすることが出来ます。
型定義の際のTypoがなくなり便利なんですが、環境構築の時点で様々なつまづきポイントがあったので、備忘録がてら記事にしました。
なお、今回はGitHub GraphQL APIを使って説明をします。

## 対象
- これまでAPIで取得したデータを手動の型定義を自動化したいが、やり方がわからない方
- GraphQL Code Generatorの仕組みがイマイチよくわからない方

## 環境
- Next.js
- GitHub GraphQL APIでデータを取得するための準備が出来ている
（GitHubトークンを取得し、エクスプローラーなどでクエリが作成できている）

## 初期設定（パッケージのインストールやcodegen.ymlの生成）
まずは公式サイトから必要なものを全てインストールしてください。

https://www.the-guild.dev/graphql/codegen/docs/getting-started/installation

この中の手順にある
```javascript
yarn graphql-code-generator init
```
を実施するとcodegen.ymlが作成されますが、その際の設定などはこちらのサイトがわかりやすかったので紹介します。

https://qiita.com/setsumaru1992/items/79fbba24e9a08899bfb6

どれも後で変更できますので、とりあえずエンターまたは表示の例に従って打ち込んで先に進んでも構いません！

:::note warn
この記事を書いている2022年9月28日に@graphql-codegen/cli"の最新バージョンが2.13.1となりましたが、その影響か正常にinitが行われなかったため、2.12.1にダウングレードして使用しています。
:::

とりあえず出来あがったcodegen.ymlファイルはこんな感じです。
ここまでは割とスムーズだったかと思います。
```yaml
overwrite: true
schema: "http://localhost:4000"
documents: "src/**/*.graphql"
generates:
  src/generated/graphql.tsx:
    plugins:
      - "typescript"
      - "typescript-operations"
      - "typescript-react-apollo"
  ./graphql.schema.json:
    plugins:
      - "introspection"

```
## codegen.ymlの設定を変更する
ここが一番大事です。ここでGraphQL APIから取得したデータに型定義がつくように設定を行います。
慣れるまで難しく感じるかもしれませんが、まずは一つ一つ設定をしていきましょう。
くどいですが、頑張りどころですからね！

### schema
schemaは、型を生成する元となる参照先のことです。
通常はエンドポイントかGraphQL APIの提供元が出すスキーマを利用します。
GitHubのGraphQL APIにはパブリックスキーマというものがあり、これをダウンロードして利用します。
ダウンロードファイルはschema.docs.graphqlとしてルート直下に置き、それを利用します。
```yaml
schema: "./schema.docs.graphql"
```

https://docs.github.com/ja/graphql/overview/public-schema

### document
documentはエンドポイントからデータを取得する際のクエリを設定します。
GitHubのGraphQL APIですとエクスプローラーを使ってUIから作成できます。

作成したデータはルート直下に置きます。今回はquery.graphqlとファイル名をつけたので、以下のような設定になります。
```yaml
documents: "./query.graphql"
```
なお、作成したクエリの中身を参考に掲載します。
内容は、5件分のリポジトリを最新の更新順に取得するもので、作成日や更新日、リポジトリのURL情報などがとれるように設定しています。
```javascript
query UseGitHubInfo {
    user(login: "topaoad") {
      name
      url
      repositories(last: 5, orderBy: {field: UPDATED_AT, direction: ASC}) {
        totalCount
        nodes {
          name
          description
          createdAt
          updatedAt
          url
          forkCount
          stargazerCount
          languages(orderBy: {field: SIZE, direction: DESC}, last: 10) {
            totalCount
            totalSize
            edges {
              node {
                id
                name
                color
              }
              size
            }
          }
        }
      }
    }
  }
```

https://docs.github.com/ja/graphql/overview/explorer

### generates
generatesはschemaとdocumentの設定を元に作成された設定ファイルを格納するパスや、ファイル作成時に使用するプラグインを設定します。
作成後のファイルは型の定義用なので、私は他の手動定義ファイルと同様にtypes配下のパスを設定しました。
好き好きなので、任意の場所を設定してかまいません。
```yaml
generates:
  src/types/githubGraphQL.ts:

```

なお、プラグインについてはデフォルトのままにしておいてください。

:::note info
簡単なまとめ
documentsに設定したGraphQL APIのエンドポイントから取得する際のクエリに対し、schemaの型定義情報と突合する。
その後、型を付与したファイルを作成し、generatesのルートに格納する。
といった仕組みです。
:::

中身を整理した後のcodegen.ymlファイルはこんな感じです。
```yaml
overwrite: true
schema: "./schema.docs.graphql"
documents: "./query.graphql"
generates:
  src/types/githubGraphQL.ts:
    plugins:
      - "typescript"
      - "typescript-operations"
      - "typescript-react-apollo"

```
※  ./graphql.schema.json:以下は使用しないので削除しました。


## 型定義ファイルを生成する
ここまで終わったらいよいよ型定義ファイルの生成なんですが、生成に必要なコマンドは実はpackage.jsonのscriptsの中に
**codegen": "graphql-codegen --config codegen.yml**とすでに設定がされています。
（初期化の際のデフォルトがcodegenとなっているため、指示に従って初期化するとこうなります）
```json
"scripts": {
        "dev": "next dev",
        "build": "next build",
        "start": "next start",
        "lint": "next lint",
        "codegen": "graphql-codegen --config codegen.yml"  
    }
```
なので、npmやyarnでcodegenを走らせてください。
すると、codegen.yml内のgeneratesに設定したディレクトリ（src/generated/graphql.tsx）にファイルが出来上がっているはずです。
（何万行にも及ぶexport typeなどで構成されたコードなので、掲載は省略します。）

## 作成後の使い方
作成した型定義ファイルを用いてGraphQL APIのエンドポイントから取得したデータに型付けすることができます。
私的にはApollo Clientを使用したデータ取得がわかりやすかったので、そのやり方も記事にしました。
もしよけば[こちらの記事](https://qiita.com/toproad/items/24e517e3e7773ef2d318 "こちらの記事")もご覧ください。

## 最後に
最初は馴染みのない設定が多く、戸惑うことも多いかと思います。
実装内容自体は型付けファイルの作成という地味なものですが、今後ますます必須のスキルになるかと思います。
少しでも理解が追い付かず困っている方の助けになれば幸いです。