💨

graphqL-code-generatorをセットアップしますた

2021/07/10に公開

graphqL-code-generatorとは、GraphQLのスキーマからTypeScriptの型を自動生成してくれるライブラリです。便利です。

普段、何気なく使ってたのですがセットアップ周りとか、あんま知らないなあ。。。
と思ったのでセットアップしてみました。
備忘録で残します。


  1. 初期セットアップ
npx create-react-app graphql-codegen-github-app --template typescript

でappを作成します。

次に、パッケージをinstallします。

yarn add @apollo/client graphql

  1. src/graphql/documents.tsを作成します。
    documents.tsの内容は以下です。(今回はGitHub GraphQL APIのスキーマからTypeScriptの型を自動生成します)
documents.ts
import { gql } from '@apollo/client';

gql`
  query Repositories($first: Int, $query: String!) {
    search(first: $first, query: $query, type: REPOSITORY) {
      repositoryCount
      # リポジトリ情報
      edges {
        node {
          ... on Repository {
            # リポジトリ名
            name
          }
        }
      }
    }
  }
`;

内容としては、引数のqueryに対応したリポジトリ情報を先頭からfirst件、取得するといったQueryを定義しました。


  1. graphqL-code-generatorをセットアップ
yarn add -D @graphql-codegen/cli @graphql-codegen/typescript
yarn graphql-codegen init

yarn graphql-codegen initの質問はデフォルトのままエンターで大丈夫です。
最後のコマンド名の質問はgenerateで打ってください。

ここで、アプリ直下にcodegen.ymlが作成されます。
codegen.ymlを以下のように書き換えてください。

codegen.yml
overwrite: true
schema: 'schema.graphql'
generates:
  src/graphql/generate/index.ts:
    documents: 'src/graphql/documents.ts'
    plugins:
      - 'typescript'
      - 'typescript-operations'
      - 'typescript-react-apollo'

内容としては、src/graphql/documents.tsを参照して、schema.graphqlで定義されてるスキーマをTypescirptの型でsrc/graphql/generate/index.tsに自動で吐き出すといった内容です。


  1. schema.graphqlを作成

いったんここでyarn generateを実行してみると以下のようなerrorがでます。
Unable to find any GraphQL type definitions for the following pointers:
schema.graphqlがないみたいなことを言ってますね。
僕がcode-generatorを使いやすいななと思うところは、errorがとてもわかりやすいところです。

ここからは、あえてエラーを出しながら進めます。(うざいですがご了承ください🙏)
では改めてschema.graphqlを作成します。

schema.graphql
type Query {
  search(
    first: Int
    query: String!
    type: SearchType!
  ): SearchResultItemConnection!
}

内容はGitHub GraphQL APIのDocをそのまま記載しました。
ここで再度yarn generateを行うとエラーが出ます。
Error: Unknown type: "SearchResultItemConnection".

SearchResultItemConnectionが定義されてないので、定義します。

schema.graphql
type SearchResultItemConnection {
  repositoryCount: Int!
  edges: [SearchResultItemEdge]
}

type Query {
  search(
    first: Int
    query: String!
    type: SearchType!
  ): SearchResultItemConnection!
}

再度yarn generateを実行でエラーが出ます
Error: Unknown type: "SearchType".
SearchTypeが定義されてないので、定義します。

schema.graphql
type SearchResultItemConnection {
  repositoryCount: Int!
  edges: [SearchResultItemEdge]
}

enum SearchType {
  REPOSITORY
}

type Query {
  search(
    first: Int
    query: String!
    type: SearchType!
  ): SearchResultItemConnection!
}

再度yarn generateを実行でエラーが出ます
Error: Unknown type: "SearchResultItemEdge".
SearchResultItemEdgeが定義されてないので、定義します。

schema.graphql
type SearchResultItemEdge {
  node: SearchResultItem
}

type SearchResultItemConnection {
  repositoryCount: Int!
  edges: [SearchResultItemEdge]
}

enum SearchType {
  REPOSITORY
}

type Query {
  search(
    first: Int
    query: String!
    type: SearchType!
  ): SearchResultItemConnection!
}

再度yarn generateを実行でエラーが出ます
Error: Unknown type: "SearchResultItem".
SearchResultItemが定義されてないので、定義します。

schema.graphql
interface Repository {
  name: String!
}

type SearchResultItem implements Repository {
  name: String!
}

type SearchResultItemEdge {
  node: SearchResultItem
}

type SearchResultItemConnection {
  repositoryCount: Int!
  edges: [SearchResultItemEdge]
}

enum SearchType {
  REPOSITORY
}

type Query {
  search(
    first: Int
    query: String!
    type: SearchType!
  ): SearchResultItemConnection!
}

再度yarn generateを実行でついに成功しsrc/graphql/generate/index.tsが生成されました。

後は自動生成されたuseRepositoriesQueryを使用してみると型補完が効くように
なります。

おわり。

Discussion