AWS AppSync リゾルバ (VTL) の書き方サンプル No.5 – Amazon DynamoDB UpdateItem

こんにちは、広野です。

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

本記事では、VTL の書き方にフォーカスしています。ご了承ください。
AWS AppSync、リゾルバ、VTL の説明については以下の記事をご覧下さい。

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 公式ドキュメントのコードが非常に良くできているので、ほぼそのまま使えます。

本記事が皆様のお役に立てれば幸いです。

著者について
広野 祐司

AWS サーバーレスアーキテクチャを駆使して社内クラウド人材育成アプリとコンテンツづくりに勤しんでいます。React で SPA を書き始めたら快適すぎて、他の言語には戻れなくなりました。サーバーレス & React 仲間を増やしたいです。AWSは好きですが、それよりもAWSすげー!って気持ちの方が強いです。
取得資格:AWS 認定は12資格、ITサービスマネージャ、ITIL v3 Expert 等
2020 - 2023 Japan AWS Top Engineer 受賞
2022 - 2023 Japan AWS Ambassador 受賞
2023 当社初代フルスタックエンジニア認定
好きなAWSサービス:AWS Amplify / AWS AppSync / Amazon Cognito / AWS Step Functions / AWS CloudFormation

広野 祐司をフォローする
クラウドに強いによるエンジニアブログです。
SCSKは専門性と豊富な実績を活かしたクラウドサービス USiZE(ユーサイズ)を提供しています。
USiZEサービスサイトでは、お客様のDX推進をワンストップで支援するサービスの詳細や導入事例を紹介しています。
AWSアプリケーション開発クラウドソリューション
シェアする
タイトルとURLをコピーしました