AmplifyのAppSyncのVTLカスタムリゾルバを最短でキャッチアップしたいメモ
雰囲気で理解していた、というか理解を後回しにしていたAppSyncのリゾルバ周りを改めて学び直しをして、最強無敵怖いもの無しになる
まだよくわかっていないもの
- あるModelから別のModelを呼び出すことを命令しているのは誰? → 回答
AppSyncの認識
-
AWSで動いている何かなどをGraphQLのインターフェースで読み書きするのを手助けしてくれる製品
- 代表的なものとしてはDynamoDBとかLambdaとか
- リクエストはおおまかに次の流れで捌かれる様子:
- HTTPリクエスト (GraphQL形式)
- リクエスト リゾルバ (JavaScript または VTL で記述)
- 各データソース (DynamoDBとかLambdaとか)
- レスポンス リゾルバ
- HTTPレスポンス
VTLの認識
- Velocity Template Language
- ApacheがJavaベースで作っているンプレートエンジン Velocity のDSL
- 文字列 (GraphQLクエリ) を文字列 (DynamoDBリクエスト等) に変換する役割を持っている
- Amplifyが自動生成するのはすごい仰々しいスクリプトという感じだけど、AWSのドキュメントのシンプルな例を見ると腹落ちする
- 入力のargumentsをDynamoDB向けの形式に変換してるだけだ!
どうしてVTLを使うのだろう
- 正直核心的なところはわからない
- データの変換をするのに必要十分で軽量・簡素だったから?
- Apacheが作ってることも作用しているかもしれない
AppSyncによるVTLの味付け
$ctx
コンテキストオブジェクトということだけわかる
本来AppSync側で定義しているのは $context
らしいので、これはAmplifyの方言かも
Amplify の自動生成コードから見つけられたもの
名前を信じて雰囲気で理解 (なんでargsとargumentsがあるのかは謎)
$ctx.args
$ctx.arguments
$ctx.error
$ctx.identity
$ctx.prev
$ctx.request
$ctx.result
$ctx.source
$ctx.stash
$util
「util のユーティリティヘルパー - AWS AppSync」に全てが載っているっぽい
親Modelが子Modelのレスポンスを含む関係の解決
AppSyncにおける主な登場人物は (コンソールのナビゲーションの通り) 3つ
- スキーマ: モデルとそれら同士の関係性の定義
- データストア: 実際のデータや処理を持つもの
- 関数: リゾルバー (AppSync↔︎データストアのリクエスト/レスポンスの変換 (解決))
例えば Team
モデルに members: [Member]
というプロパティがスキーマとして定義されていて、 Team
と Member
それぞれのDynamoDBテーブルがあったとする
この時、関数はこれら親子関係の紐付けは担わず 、専ら「Team
の解決」「Member
の解決」のみを責任とする
(「TeamのリゾルバがMemberリゾルバを呼ぶ」みたいなことはしていないイメージ)
AppSyncの中心的な価値の1つは、これらの関数のオーケストレーションをスキーマベースに行い、クライアントの問い合わせに応じて呼び分けたり、入れ子構造を解決してくれることなのだとわかった
リゾルバ同士の実行フロー
実行フローのイメージはJavaScriptリゾルバの方のページ記載があった
上記の例なら、以下のようなイメージかな
- 実行: Teamリクエストリゾルバ
- 入手: Teamのデータ入手
- 実行: Memberリクエストリゾルバ
- 入手: Memberのデータ入手
- 実行: Memberレスポンスリゾルバ
- 実行: Teamリクエストリゾルバ
Amplifyが自動生成するリゾルバの読み方
ここに書いてあった
(Queryの場合)
-
init
: 初期化 (デフォルト値の設定など用) -
preAuth
: 認可の前処理 -
auth
: 認可処理本体 -
postAuth
: 認可の後処理 -
preDataLoad
: データソースへの問い合わせの前処理 -
postDataLoad
: データソースへの問い合わせの後処理 -
finish
: 完了処理 (クリーンアップなど)
$utils.qr
とは何か
頻出の
ここに書いてあるが、新参者にとっては難しい
おそらく、引数が返ってくる関数はそのまま出力に含まれてしまうけど、これを抑制するためのユーティリティで、#if
の条件式等じゃないところで呼び出す時に使っているように見える
要するに空気
#return
と #return($util.toJson(null))
は違う
VTLリゾルバの
-
#return
: キーを残さずに終了する -
#return($util.toJson(null))
キーに対する値としてnullを持たせて終了する
VTLリゾルバってこの辺りで作っているのだなあ