AWS Amplify のスキーマ定義が codegen から生成される型定義に含まれない場合がある

SCSKの畑です。

今回は小ネタですが、アプリケーション開発中に少し戸惑った内容であることと、(あまりにも当たり前すぎて?)Web 上にあまり情報が見つけられなかったことも相まってエントリとして残しておこうと思っての投稿です。

小ネタ本題

先般投稿した一連のエントリの通り、アプリケーションのバックエンドからフロントエンドまで広く手を入れることになりましたが、その際に Amplify・AppSync 周りで遭遇した内容となります。

AWS AppSync の制約を回避するためのアプリケーション改修その1:概要編
昨年度リリースした Web アプリケーションにおける AppSync の制約を回避するためのアプリケーション改修について説明します。第1回は概要編です。
AWS AppSync の制約を回避するためのアプリケーション改修その2:バックエンド編
昨年度リリースした Web アプリケーションにおける AppSync の制約を回避するためのアプリケーション改修について説明します。第2回はバックエンド編です。
AWS AppSync の制約を回避するためのアプリケーション改修その3:フロントエンド編
昨年度リリースした Web アプリケーションにおける AppSync の制約を回避するためのアプリケーション改修について説明します。第3回はフロントエンド編です。

これら一連の改修においては当然ながら AppSync API(スキーマ定義)も複数変更されており、上記エントリで言及した非同期処理用インターフェース/ラッパー用クエリの追加もあれば、同クエリ経由で非同期実行するように変更することで不要となったクエリ/ミューテーションの削除もありました。上記エントリで触れたテーブルの更新差分を導出する処理を例に挙げますと、一連の処理が AppSync クエリとして実装されていたところを

  • 差分計算処理:非同期処理用インターフェース/ラッパー用クエリ経由の実行に変更
  • 差分計算結果取得処理:S3 署名付き URL 経由での取得処理に変更

のように変更したため、元々の AppSync クエリは結果的に不要となり、Amplify のスキーマ定義からも削除しました。

一方で、差分計算結果のフォーマット(型情報)自体は変更する必要がなかったため、元々の AppSync クエリの返り値として Amplify のスキーマに定義していたものを引き続き使用しようと考え残しておきました。スキーマ定義の詳細については昨年度の以下エントリをご参照ください。

Amplify codegen で自動生成される query にネストされた type が 含まれない
タイトルの通り、Amplify codegen で自動生成される query にネストされた type が 含まれない事象が発生したため、原因と解決策についてまとめてみました。
なお、この差分計算結果のフォーマットは、データ量の増大に伴いパフォーマンス改善の必要が生じたため、今年度改修しています。詳細な内容は改めて別のエントリで触れたいと思います。
ところが、一連の変更後にアプリケーションの動作確認をしたところ、差分計算結果取得処理においてアプリケーション側で以下のようなエラーが発生していました。文字通り、上記フォーマットの型情報が未定義で取得できなかったというエラーです。
name: TypeError
message: can't access property "deleted_rows_info", models.DataDiffInfo is undefined
おかしいな、Amplify のスキーマ定義にはそのまま残してあるのに・・と思いながら、Amplify が自動生成する型情報の定義ファイルとなる API.ts を参照したところ、上記フォーマットに対応する型情報の定義が全て削除されていました。そりゃ未定義と怒られる訳ですが、では何故削除されてしまったのかと言うと、、もうお分かりでしょうが Amplify のスキーマ定義から対象のクエリを削除したことが原因でした。
というのも、この差分計算結果のフォーマット(型情報)は、対象のクエリの返り値の定義にしか含まれていなかったんですね。つまり、Amplify のスキーマ定義から対象のクエリを削除すると、Amplify・AppSync で定義される一連の処理(クエリ/ミューテーション/サブスクリプション)内でこのフォーマットが使用されなくなるため、Amplify(amplify codegen)により生成される型情報からも削除されるものと理解しました。Amplify スキーマ定義の目的が AppSync の graphql の仕様を定義するためと考えると、まあ当たり前と言えば当たり前の話ではあるのですが・・試しにスキーマ定義を元に戻したところ、API.ts 内の型情報定義も元に戻ったことも裏付けとなりました。
最も、AppSync のスキーマ定義自体には上記の型情報が含まれたままとなっていたので、若干一貫性のない仕様と感じてしまった部分もあります。このへんも Amplify gen2 ではそもそものスキーマ定義の方法が異なる以上、同様に変わっているところかもしれませんが・・

回避策

先述の通り、Amplify が生成する型情報に含めるためには廃止したクエリを(使わないのに)再度定義する必要があるということで、さすがにそれは目的と手段を履き違えているため、大人しくこれらの型情報を定義するための composable を作成することで対応しました。

Amplify 経由で定義する方が正直楽ではあるので最初はその方向性で調査していたのですが情報がまるでなく。。一旦上記で解決したこともあり直近では特に調査していないのですが、もし今後続報があれば本エントリを更新したいと思います。

まとめ

先述の通り、Amplify のスキーマの目的というか位置づけを考えるとそのような挙動になることは納得の行くところですが、そもそも普通は Amplify/AppSync で使用しない型情報を明示的に Amplify のスキーマに定義することはないと思うので、そう考えるとある意味盲点と言えるかもしれません。。アプリケーション開発中に AppSync クエリの改廃自体は発生し得ることだとは思いますが、今回のように AppSync のクエリとしては不要になったが型情報は継続して使用したいというのもレアケース寄りだと思いますし・・

本記事がどなたかの役に立てば幸いです。

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