LoginSignup
2

More than 1 year has passed since last update.

AppSyncでDynamoDBのトランザクション処理

Last updated at Posted at 2022-12-03

はじめに

この記事は NTTテクノクロスAdvent Calendar 2022 の 4日目の記事です。

NTTテクノクロスの井上です。
普段はAWS関連の業務をしています。

この記事では、
AppSyncでDynamoDBのトランザクション処理をおこなう方法についてご紹介します。

目次

  1. 構成
  2. DynamoDB
  3. IAM
  4. AppSync
  5. 実行

構成

作成するアーキテクチャはこのような図になります。

DynamoDBの2つのテーブルに、同時にデータを書き込む処理を作ります。

構成図.png

DynamoDB

この記事で扱うテーブルの定義はこちらの通りです。

  • FooTable
カラム名
ID String パーティションキー
foo String -
  • BarTable
カラム名
ID String パーティションキー
bar String -

IAM

AppSyncにDynamoDBの権限を付与するためにロールを作成します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:DeleteItem",
                "dynamodb:GetItem",
                "dynamodb:PutItem",
                "dynamodb:Query",
                "dynamodb:Scan",
                "dynamodb:UpdateItem"
            ],
            "Resource": [
                "arn:aws:dynamodb:ap-northeast-1:<アカウントID>:table/FooTable",
                "arn:aws:dynamodb:ap-northeast-1:<アカウントID>:table/FooTable/*",
                "arn:aws:dynamodb:ap-northeast-1:<アカウントID>:table/BarTable",
                "arn:aws:dynamodb:ap-northeast-1:<アカウントID>:table/BarTable/*"
            ]
        }
    ]
}

AppSync

データソース

データソースを作成します。

テーブル名は、トランザクションオペレーションのリクエストマッピングテンプレートで指定するので、何でも構いません。

項目 設定値
データソース名 FooTable
データソースタイプ Amazon DynamoDB テーブル
リージョン AP-NORTHEAST-1
テーブル名 FooTable
既存のロールを作成または使用する 先ほど作成したIAMロールを選択

スキーマ

スキーマを作成します。

この例では、次のことをおこなうためにTransactWriteItemsを使用します。

  • FooTableにfooデータを登録・更新
  • BarTableにbarデータを登録・更新
type Bar {
	id: String!
	bar: String
}

input BarInput {
	id: String!
	bar: String
}

type Foo {
	id: String!
	foo: String
}

input FooInput {
	id: String!
	foo: String
}

type Mutation {
	transactTests(Bar: [BarInput], Foo: [FooInput]): TransactionResult
}

type Query {
	getFoo(id: String!): Foo
	getBar(id: String!): Bar
}

type TransactionResult {
	foo: [Foo]
	bar: [Bar]
}

schema {
	query: Query
	mutation: Mutation
}

リゾルバー

transactTestsのリゾルバーを作成します。

データソースには先ほど作成したFooTableを選択します。

リクエストマッピングテンプレート

#set($BarTransactPutItems = [])
#set($index = 0)
#foreach($Bar in ${ctx.args.Bar})
  #set($keyMap = {})
  $util.qr($keyMap.put("id", $util.dynamodb.toString($Bar.id)))
  #set($attributeValues = {})
  $util.qr($attributeValues.put("bar", $util.dynamodb.toString($Bar.bar)))
  #set($index = $index + 1)
  #set($BarTransactPutItem = {"table": "BarTable",
      "operation": "PutItem",
      "key": $keyMap,
      "attributeValues": $attributeValues})
  $util.qr($BarTransactPutItems.add($BarTransactPutItem))
#end

#set($FooTransactPutItems = [])
#set($index = 0)
#foreach($Foo in ${ctx.args.Foo})
  #set($keyMap = {})
  $util.qr($keyMap.put("id", $util.dynamodb.toString($Foo.id)))
  #set($attributeValues = {})
  $util.qr($attributeValues.put("foo", $util.dynamodb.toString($Foo.foo)))
  #set($index = $index + 1)
  #set($FooTransactPutItem = {"table": "FooTable",
      "operation": "PutItem",
      "key": $keyMap,
      "attributeValues": $attributeValues})
  $util.qr($FooTransactPutItems.add($FooTransactPutItem))
#end

#set($transactItems = [])
$util.qr($transactItems.addAll($BarTransactPutItems))
$util.qr($transactItems.addAll($FooTransactPutItems))

{
    "version" : "2018-05-29",
    "operation" : "TransactWriteItems",
    "transactItems" : $util.toJson($transactItems)
}

レスポンスマッピングテンプレート

#if ($ctx.error)
    $util.appendError($ctx.error.message, $ctx.error.type, null, $ctx.result.cancellationReasons)
#end

#set($bar = [])
$util.qr($bar.add(${ctx.result.keys[0]}))

#set($foo = [])
$util.qr($foo.add(${ctx.result.keys[1]}))

#set($transactionResult = {})
$util.qr($transactionResult.put('bar', $bar))
$util.qr($transactionResult.put('foo', $foo))

$util.toJson($transactionResult)

実行

実際にクエリを打って正しく動くか試してみます。

  • クエリ
    左側が送ったクエリ、右側が返ってきた値です。
    6-1.png

  • FooTable
    6-3.png

  • BarTable
    6-4.png

2つのテーブルに正しく登録されたことを確認できました。

おわりに

今回は、AppSyncでDynamoDBのトランザクション処理をおこなう方法をご紹介しました。
少しでも参考にしていただけたら嬉しいです。

では、NTTテクノクロスAdvent Calendar 2022 の 5日目も、お楽しみください!

参考

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2