Amplify codegen で自動生成される query にネストされた type が 含まれない

SCSKの畑です。

Amplify を使用したアプリケーション開発中に発生した事象の原因及び解決策について、Web 上にあまり情報がなかったことも含めて解決に少々手こずったので共有します。引き続き今回も小ネタです。

 

小ネタ本題

タイトルの繰り返しになるのですが、以下のようなスキーマを定義した際、Amplify codegen により生成された query にネストされた type が含まれなかったという事象が発生しました。ちなみに本スキーマは2つの Redshift テーブルの定義及びデータを差分比較結果を格納するためのもので、AddedRowsInfo/DeletedRowsInfo/UpdatedRowsInfo に差分のあった行情報がネストされて格納されます。

ちなみに、差分比較処理自体は素直に AppSync から Lambda リゾルバを使用して実現していますが、フロントエンド側での表示も含めてそこそこ苦労した部分なので、機会があれば別エントリとして書くかもしれません。
type DataDiffInfo {
  diff_summary: RSS3DiffStatus!
  added_rows_info: [AddedRowsInfo]!
  deleted_rows_info: [DeletedRowsInfo]!
  updated_rows_info: [UpdatedRowsInfo]!
}

type RSS3DiffStatus{
  column: Boolean
  constraint: Boolean
  data: Boolean
}

type PKInfo {
  name: String!
  value: String!
}

type AddedRowsInfo {
  pk: [PKInfo!]!
  row_data: String!
}

type DeletedRowsInfo {
  pk: [PKInfo!]!
  row_data: String!
}

type UpdatedRowsInfo {
  pk: [PKInfo!]!
  cols: [String!]!
  row_data: String!
}

で、このスキーマ定義に対して、codegen で生成された typescript の query が以下になるのですが・・

export const GetTableDataDiffInfo = /* GraphQL */ `query GetTableDataDiffInfo($input: GetTableDataDiffInfoInput!) {
  GetTableDataDiffInfo(input: $input) {
    diff_summary {
      column
      constraint
      data
      __typename
   }
    added_rows_info {
      row_data
      __typename
    }
    deleted_rows_info {
      row_data
      __typename
    }
    updated_rows_info {
      cols
      row_data
      __typename
    }
    __typename
  }
}
` as GeneratedQuery<
  APITypes.GetTableDataDiffInfoQueryVariables,
  APITypes.GetTableDataDiffInfoQuery
>;

見てお分かりの通り、AddedRowsInfo/DeletedRowsInfo/UpdatedRowsInfo 配下の「PKInfo」type 部分が query 定義から抜け落ちてしまっています。ネストの深さとしては一番上の階層から数えると「3」になりますね。

 

暫定回避策

さてこれは困ったということで解決策を探したのですが、探し方が悪かったのかめぼしい情報が見当たらず。最初は AppSync のクエリの深さ制限設定を疑ったのですが、デフォルト値は無制限だったためこの可能性は除外。

そこで一旦暫定的な回避策として、自分で直接 GraphQL の query を書くことにしました。codegen で 型情報を生成して欲しかったので、以下サイト様の記事通り所定のパスに query が定義されたファイルを配置しました。

AmplifyでカスタムGraphQLクエリと型情報を生成する方法 - Qiita
本記事を対象とする人Web(React,Vueなど)でAmplify利用し、自動生成されるクエリでは足りなくなった結論graphqlconfig.ymlのincludesに指定しているディレク…

ただ、当然ながら query を自分で書いている以上スキーマ定義の変更があった場合も自動で追随してくれないため、開発が続くにつれて不便さ&イライラを感じてきました。そもそも、Amplify が自動生成しないような複雑なクエリを書きたいから自分で書く必要があるのであって、今回のような事象に対しては根本的な解決策でないことは明らかであったため、本腰を入れて解決策を調べたところ・・

 

解決策

結論としては以下 URL の通り、.graphqlconfig.yml の maxDepth 属性で、生成する query のネストの深さを明示的に指定することで解決しました。ただ、以下 URL に記載のある –max-depth オプションは手元の環境だと機能しませんでした。また、「maxdepth」のように大文字小文字を間違えてもダメですのでご注意ください。最初間違えてしまったのですが、エラーも出ないのでこの設定方法も機能しないのではないかと疑心暗鬼になってしまいました・・

Nested types missing from queries in generated code - Require workaround · Issue #745 · aws-amplify/amplify-cli
** Which Category is your question related to? ** iOS side generated graphql queries ** What AWS Services are you utiliz...

以下、maxDepth を 5 に設定した場合の実装例です。

projects:
  nuxt3app:
    schemaPath: src/graphql/schema.json
    includes:
      - src/graphql/**/*.ts
    excludes:
      - ./amplify/**
    extensions:
      amplify:
        codeGenTarget: typescript
        generatedFileName: src/API.ts
        docsFilePath: src/graphql
        maxDepth: 5
extensions:
  amplify:
    version: 3

こちらはオプション指定して codegen した query の内容です。PKInfo の type が追加されていることが確認できます。

export const GetTableDataDiffInfo = /* GraphQL */ `query GetTableDataDiffInfo($input: GetTableDataDiffInfoInput!) {
  GetTableDataDiffInfo(input: $input) {
    diff_summary {
      column
      constraint
      data
      __typename
    }
    added_rows_info {
      pk {
        name
        value
        __typename
      }
      row_data
      __typename
    }
    deleted_rows_info {
      pk {
        name
        value
        __typename
      }
      row_data
      __typename
    }
    updated_rows_info {
      pk {
        name
        value
        __typename
      }
      cols
      row_data
      __typename
    }
    __typename
  }
}
` as GeneratedQuery<
  APITypes.GetTableDataDiffInfoQueryVariables,
  APITypes.GetTableDataDiffInfoQuery
>;

また、同オプションのデフォルト値は「2」ということで、先般のスキーマ定義において PKInfo 以下の type が出力されなかった理由も辻褄が合ってスッキリしました。正直、デフォルト値はもう少し大きくても良いと思うんですけども・・

 

まとめ

以前の投稿にて Amplify.Configure に与える引数の定義が不明瞭で調査に苦労した旨書いていたのですが、本件も似たような文脈の話ではないかと思います。。

余談ですが、初めて本事象が発生した時は原因究明に結構な時間を要してしまいました。というのも、Amplify のデプロイや codegen 実行時はエラーが出ておらず、AppSync 側のスキーマ定義を確認しても問題なし。Lambda リゾルバの実装に問題がある可能性も考慮して、AWS マネジメントコンソールからクエリを直接実行してみるとちゃんと PKInfo 部分の情報も取れる。でもフロントエンド側から codegen で生成されたクエリを使用すると PKInfo 部分の情報が取れない。でもエラー自体は出ていない。という感じだったので・・

開発当初は Amplify や AppSync、GraphQL などへの理解が十分でなかったこともありますが、Web 上の情報がもう少し多かったらもっと早く解決できた!はず!ということで小ネタではありますが、本記事がどなたかの役に立てば幸いです。

タイトルとURLをコピーしました