graphql-codegenをAWS AppSync, TypeScriptでやりたい

AWSでGraphQLを使う際のサービス、AWS AppSyncにcodegenを導入する際に詰まったのでメモ。 基本的なコマンドやドキュメントはこちらを見ます。 なお、私はpackage managerはyarnが好きなのでyarnを使用します。npmでもやることは特に変わりません。

www.graphql-code-generator.com

codegenをinstall

まずはgraphqlをインストール。

$ yarn add graphql

devにcodegenをインストール。

$ yarn add -D @graphql-codegen/cli

初期ファイルをセットアップ

対話形式でセットアップします。 後で修正する部分もあるのでとりあえず下記のように初期セットアップ。

$ yarn graphql-codegen init
yarn run v1.22.10
$ /Users/xxxxx/yyyy/node_modules/.bin/graphql-codegen init

    Welcome to GraphQL Code Generator!
    Answer few questions and we will setup everything for you.
  
? What type of application are you building? Backend - API or server
? Where is your schema?: (path or url) http://localhost:4000
? Pick plugins: TypeScript (required by other typescript plugins)
? Where to write the output: src/generated/graphql.ts
? Do you want to generate an introspection file? Yes
? How to name the config file? codegen.yml
? What script in package.json should run the codegen? codegen
Fetching latest versions of selected plugins...

    Config file generated at codegen.yml
    
      $ npm install

    To install the plugins.

      $ npm run codegen

    To run GraphQL Code Generator.
  
✨  Done in 82.03s.

TypeScriptも使いたいのでインストールします。

$ yarn add -D @graphql-codegen/typescript

initをしたらcodegen.ymlというファイルが生成されます。

対話形式で選択したような感じに初期セットアップがされていますが、私は下記のように書き換えました。 - schemaを指定する - 不必要な部分を削除

overwrite: true #上書きを許可する
schema:
  - ./schema.graphql 
  - ./schema/**/*.graphql # コード量が多くなってきたときに備えてグローバル分割しておく


generates:
  ./src/generated/graphql.ts:
    plugins:
      - "typescript"

package.jsonのscriptsを少し修正します。

"scripts": {
    ...
    "codegen": "yarn graphql-codegen"
 },

任意のschemaを記述します。

こちらは後々のために最小限の記述にしておきます。

schema.graphql

schema {
  query: Query
  mutation: Mutation
}

適当なschemaを記述します。

schema/hoge.graphql

type Query {
  getHoge: [Hoge!]
}

type Hoge {
  id: ID
  createdAt: AWSDateTime
  title: String!
  description: String!
}
...

これでyarn codegenというコマンドを実行すればschemaが自動生成されるはずのつもりでした。

Type "AWSDateTime" not found in document. Error: Type "AWSDateTime" not found in document.

yarn codegenを実行すると下記のエラーが出てしまいました。

$ yarn codegen

...
src/generated/graphql.ts
    Failed to load schema from ./schema.graphql,./schema/**/*.graphql:

        Type "AWSDateTime" not found in document.
        Error: Type "AWSDateTime" not found in document.


https://benoitboure.com/how-to-use-typescript-with-appsync-lambda-resolvers

AWS AppSync特有のプロパティであるAWSDateTimeを使用しているため対応が必要でした。

schema以下に新たなファイルを追加します。

schema/appsync.graphql

scalar AWSDateTime

codegen.ymlにも追記が必要です。

schema:
  - ./schema.graphql
  - ./schema/**/*.graphql

# 以下を追記
config: 
  scalars:
    AWSDateTime: string

これでもう一度 yarn codegenを実行します。

エラー内容が変わりました。。。

Error: Cannot use GraphQLObjectType "Query" from another module or realm.

$ yarn codegen
...

Error: Cannot use GraphQLObjectType "Query" from another module or realm.

    Ensure that there is only one instance of "graphql" in the node_modules
    directory. If different versions of "graphql" are the dependencies of other
    relied on modules, use "resolutions" to ensure only one version is installed.

    https://yarnpkg.com/en/docs/selective-version-resolutions

    Duplicate "graphql" modules cannot be used at the same time since different
    versions may have different capabilities and behavior. The data from one
    version used in the function from another could produce confusing and
    spurious results.

こちらはターミナルにきちんと載っていました。 graphqlのバージョンが複数ある問題でした。

Selective dependency resolutions | Yarn

ドキュメントに従ってpackage.jsonに追記します。

"resolutions": {
    "graphql": "^15.5.0"
  },

依存をきちんとインストールしてあげます。

$ yarn

もう一度codegen

$ yarn codegen
yarn run v1.22.10
$ yarn graphql-codegen
$ /Users/xxxx/yyy/node_modules/.bin/graphql-codegen
  ✔ Parse configuration
  ✔ Generate outputs
✨  Done in 1.29s.

できました!