こんにちは、広野です。
AWS AppSync を使用したアプリケーションを開発する機会があり、リゾルバ、主に VTL の書き方に関してまとまった知識が得られたので紹介します。前回からの続きもので、UpdateItem の書き方を紹介します。





Amazon DynamoDB に UpdateItem する VTL
例えば、AWS AppSync から以下のリクエストを受けたとします。Amazon DynamoDB には適切なデータがある想定です。テーブル名はリゾルバの別の設定 (Data Source) で行います。
- 引数となるパラメータ: input の中にパーティションキー pkey、ソートキー skey、任意の属性データ
今回は受け取ったパーティションキーとソートキーのパラメータをそのまま UpdateItem の条件に当てはめて、input の中に格納されている属性をそのまま使用してデータを更新します。
リクエストマッピングテンプレート
{
"version": "2018-05-29",
"operation": "UpdateItem",
"key": {
"pkey": $util.dynamodb.toDynamoDBJson($ctx.args.input.pkey),
"skey": $util.dynamodb.toDynamoDBJson($ctx.args.input.skey)
},
#set( $expNames = {} )
#set( $expValues = {} )
#set( $expSet = {} )
#set( $expAdd = {} )
#set( $expRemove = [] )
#foreach( $entry in $util.map.copyAndRemoveAllKeys($ctx.args.input, ["pkey", "skey"]).entrySet() )
#if( $util.isNull($entry.value) )
#set( $discard = ${expRemove.add("#${entry.key}")} )
$!{expNames.put("#${entry.key}", "${entry.key}")}
#else
$!{expSet.put("#${entry.key}", ":${entry.key}")}
$!{expNames.put("#${entry.key}", "${entry.key}")}
$!{expValues.put(":${entry.key}", $util.dynamodb.toDynamoDB($entry.value))}
#end
#end
#set( $expression = "" )
#if( !${expSet.isEmpty()} )
#set( $expression = "SET" )
#foreach( $entry in $expSet.entrySet() )
#set( $expression = "${expression} ${entry.key} = ${entry.value}" )
#if ( $foreach.hasNext )
#set( $expression = "${expression}," )
#end
#end
#end
#if( !${expAdd.isEmpty()} )
#set( $expression = "${expression} ADD" )
#foreach( $entry in $expAdd.entrySet() )
#set( $expression = "${expression} ${entry.key} ${entry.value}" )
#if ( $foreach.hasNext )
#set( $expression = "${expression}," )
#end
#end
#end
#if( !${expRemove.isEmpty()} )
#set( $expression = "${expression} REMOVE" )
#foreach( $entry in $expRemove )
#set( $expression = "${expression} ${entry}" )
#if ( $foreach.hasNext )
#set( $expression = "${expression}," )
#end
#end
#end
"update": {
"expression": "${expression}",
#if( !${expNames.isEmpty()} )
"expressionNames": $utils.toJson($expNames),
#end
#if( !${expValues.isEmpty()} )
"expressionValues": $utils.toJson($expValues),
#end
},
"condition": {
"expression": "attribute_exists(#pkey) AND attribute_exists(#skey)",
"expressionNames": {
"#pkey": "pkey",
"#skey": "skey"
}
}
}
operation には、UpdateItem を書きます。これは Amazon DynamoDB に UpdateItem するぞ、という意思表示です。
アプリから受け取った引数はマッピングテンプレート内では $ctx.args 内に格納されます。今回は input の中に必要なキーや属性をまとめて格納しています。そうすることで、パーティションキー、ソートキー以外は任意のデータを可変で入れ込むことができます。
このコードは以下の AWS 公式サイトのドキュメントを参考にしました。正直、これを独力で書くのは難しいです。コード内、pkey と skey の部分だけ書き換えれば使えます。
レスポンスマッピングテンプレート
結果は配列に格納されます。戻ってきたデータをそのままアプリ側に戻す書き方です。
$utils.toJson($context.result)
VTL に関しては以下の AWS 公式ドキュメントも必要に応じてご確認ください。
まとめ
いかがでしたでしょうか。
UpdateItem も AWS AppSync のサブスクリプションで使用することがあります。他のオペレーションと比べて難解なコードになっていますが、AWS 公式ドキュメントのコードが非常に良くできているので、ほぼそのまま使えます。
本記事が皆様のお役に立てれば幸いです。
