翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
PutItem
、UpdateItem
、および DeleteItem
の各 DynamoDB 処理を使用して DynamoDB のオブジェクトをミューテーションする場合、オプションで、処理を実行する前に、DynamoDB にある既存のオブジェクトの状態に基づいてリクエストが成功するかどうかを制御する条件式を指定することができます。
AWS AppSync DynamoDB リゾルバーでは、PutItem
、、UpdateItem
および DeleteItem
リクエストマッピングドキュメントで条件式を指定でき、条件が失敗してオブジェクトが更新されなかった場合に従う戦略も許可されます。
例 1
以下の PutItem
マッピングドキュメントには条件式がありません。その結果、同じキーに対応する項目がすでにある場合でも、項目は DynamoDB に挿入され、それにより既存の項目が上書きされます。
{
"version" : "2017-02-28",
"operation" : "PutItem",
"key" : {
"id" : { "S" : "1" }
}
}
例 2
次の PutItem
マッピングドキュメントには条件式があります。この場合、同じキーの項目が DynamoDB に存在しない場合のみ処理が成功します。
{
"version" : "2017-02-28",
"operation" : "PutItem",
"key" : {
"id" : { "S" : "1" }
},
"condition" : {
"expression" : "attribute_not_exists(id)"
}
}
デフォルトでは、条件チェックが失敗すると、 AWS AppSync DynamoDB リゾルバーはミューテーションのエラーを返します。ただし、 AWS AppSync DynamoDB リゾルバーには、開発者が一般的なエッジケースを処理するのに役立ついくつかの追加機能があります。
-
AWS AppSync DynamoDB リゾルバーは、DynamoDB の現在の値が目的の結果と一致すると判断できる場合、オペレーションは成功したかのように扱われます。
-
エラーを返す代わりに、カスタム Lambda 関数を呼び出して AWS AppSync DynamoDB リゾルバーが障害を処理する方法を決定するようにリゾルバーを設定できます。
これらの詳細については、「条件チェックでのエラーを処理する」セクションを参照してください。
DynamoDB の条件式の詳細については、「DynamoDB ConditionExpressions のドキュメント」を参照してください。
条件を指定する
PutItem
、UpdateItem
、および DeleteItem
の各リクエストマッピングドキュメントはすべて、オプションで condition
セクションが指定できます。省略した場合、条件チェックは実行されません。指定した場合、処理が成功するには、条件が true となる必要があります。
condition
セクションは以下の構造を持ちます。
"condition" : {
"expression" : "someExpression"
"expressionNames" : {
"#foo" : "foo"
},
"expressionValues" : {
":bar" : ... typed value
},
"equalsIgnore" : [ "version" ],
"consistentRead" : true,
"conditionalCheckFailedHandler" : {
"strategy" : "Custom",
"lambdaArn" : "arn:..."
}
}
以下のフィールドに条件を指定します。
-
expression
-
更新式そのものを指定します。条件式の記述方法の詳細については、DynamoDB ConditionExpressions のドキュメントを参照してください。このフィールドの指定は必須です。
-
expressionNames
-
式の属性名のプレースホルダーを示します。キー - 値のペアの形式になります。キーは expression で使用される名前のプレースホルダーに対応し、値は DynamoDB の項目の属性名と一致する文字列でなければなりません。このフィールドはオプションであり、expression で使用される式の属性名のプレースホルダーのみを入力します。
-
expressionValues
-
式の属性値のプレースホルダーを示します。キー - 値のペアの形式になります。キーは expression で使用される値のプレースホルダーに対応し、値は型付き値でなければなりません。「型付き値」を指定する方法の詳細については、「型システム (リクエストマッピング)」を参照してください。この指定は必須です。このフィールドはオプションであり、expression で使用される式の属性値のプレースホルダーのみを入力します。
残りのフィールドは、 AWS AppSync DynamoDB リゾルバーに条件チェックの失敗を処理する方法を指示します。
-
equalsIgnore
-
PutItem
オペレーションの使用時に条件チェックが失敗すると、 AWS AppSync DynamoDB リゾルバーは、DynamoDB の現在ある項目と、書き込みを試みた項目を比較します。これらが同じ場合、処理は成功として扱われます。equalsIgnore
フィールドを使用して、 AWS AppSync がその比較を実行するときに無視する属性のリストを指定できます。たとえば、唯一の違いがversion
属性である場合、オペレーションは成功として扱われます。このフィールドはオプションです。 -
consistentRead
-
条件チェックが失敗すると、 AWS AppSync は強力な整合性のある読み込みを使用して DynamoDB から項目の現在の値を取得します。このフィールドを使用して、 AWS AppSync DynamoDB リゾルバーに、代わりに結果整合性のある読み込みを使用するように指示できます。このフィールドはオプションであり、デフォルトは
true
です。 -
conditionalCheckFailedHandler
-
このセクションでは、 AWS AppSync DynamoDB リゾルバーが DynamoDB の現在の値と予想される結果を比較した後に、条件チェック DynamoDB の失敗を処理する方法を指定できます。このセクションはオプションです。省略した場合、デフォルトの処理は
Reject
です。-
strategy
-
AWS AppSync DynamoDB リゾルバーが DynamoDB の現在の値を期待される結果と比較した後に実行する戦略。このフィールドは必須であり、以下を値を設定できます。
-
Reject
-
ミューテーションは失敗し、GraphQL レスポンスにエラーが追加されます。
-
Custom
-
AWS AppSync DynamoDB リゾルバーは、カスタム Lambda 関数を呼び出して、条件チェックの失敗を処理する方法を決定します。
strategy
がCustom
に設定されている場合、lambdaArn
フィールドには、呼び出す Lambda 関数の ARN が含まれている必要があります。
-
-
lambdaArn
-
AWS AppSync DynamoDB リゾルバーが条件チェックの失敗を処理する方法を決定する、呼び出す Lambda 関数の ARN。このフィールドは、
strategy
がCustom
に設定されている場合のみ指定する必要があります。この機能の使用方法の詳細については、「条件チェックでのエラーを処理する」を参照してください。
-
条件チェックでのエラーを処理する
デフォルトでは、条件チェックが失敗すると、 AWS AppSync DynamoDB リゾルバーはミューテーションのエラーと DynamoDB 内のオブジェクトの現在の値を返します。ただし、 AWS AppSync DynamoDB リゾルバーには、開発者が一般的なエッジケースを処理するのに役立ついくつかの追加機能があります。
-
AWS AppSync DynamoDB リゾルバーは、DynamoDB の現在の値が目的の結果と一致すると判断できる場合、オペレーションは成功したかのように扱われます。
-
エラーを返す代わりに、カスタム Lambda 関数を呼び出して AWS AppSync DynamoDB リゾルバーが障害を処理する方法を決定するようにリゾルバーを設定できます。
このプロセスのフローチャートは次のとおりです。

必要な結果をチェックする
条件チェックが失敗すると、 AWS AppSync DynamoDB リゾルバーは GetItem
DynamoDB リクエストを実行して DynamoDB から項目の現在の値を取得します。デフォルトでは、強力な整合性のある読み込みを使用しますが、condition
ブロックの consistentRead
フィールドを使用してこれを設定し、この値を期待した結果と比較することができます。
-
PutItem
オペレーションの場合、 AWS AppSync DynamoDB リゾルバーは、現在の値を書き込みを試みた値と比較equalsIgnore
対象から除外します。項目が同じ場合は、処理は成功として扱われ、DynamoDB から取得された項目が返されます。それ以外の場合は、設定された処理に従います。たとえば、
PutItem
リクエストマッピングドキュメントが以下のようになっているとします。{ "version" : "2017-02-28", "operation" : "PutItem", "key" : { "id" : { "S" : "1" } }, "attributeValues" : { "name" : { "S" : "Steve" }, "version" : { "N" : 2 } }, "condition" : { "expression" : "version = :expectedVersion", "expressionValues" : { ":expectedVersion" : { "N" : 1 } }, "equalsIgnore": [ "version" ] } }
現在、DynamoDB にある項目は以下のようになりました。
{ "id" : { "S" : "1" }, "name" : { "S" : "Steve" }, "version" : { "N" : 8 } }
AWS AppSync DynamoDB リゾルバーは、書き込もうとした項目を現在の値と比較し、唯一の違いは
version
フィールドであることを確認できますが、version
フィールドを無視するように設定されているため、オペレーションは成功として扱われ、DynamoDB から取得した項目を返します。 -
DeleteItem
オペレーションの場合、 AWS AppSync DynamoDB リゾルバーは項目が DynamoDB から返されたことを確認します。項目が返されなかった場合、処理は成功として扱われます。それ以外の場合は、設定された処理に従います。 -
UpdateItem
オペレーションの場合、 AWS AppSync DynamoDB リゾルバーには、現在 DynamoDB にある項目が期待される結果と一致するかどうかを判断するのに十分な情報がないため、設定された戦略に従います。
DynamoDB のオブジェクトの現在の状態が予想される結果と異なる場合、 AWS AppSync DynamoDB リゾルバーは設定された戦略に従ってミューテーションを拒否するか、Lambda 関数を呼び出して次に何をするかを決定します。
「reject」の戦略に従う
Reject
戦略に従うと、 AWS AppSync DynamoDB リゾルバーはミューテーションのエラーを返します。
たとえば、次のミューテーションリクエストが指定されたとします。
mutation {
updatePerson(id: 1, name: "Steve", expectedVersion: 1) {
Name
theVersion
}
}
DynamoDB から返された項目が以下のようになっているとします。
{
"id" : { "S" : "1" },
"name" : { "S" : "Steve" },
"version" : { "N" : 8 }
}
また、レスポンスマッピングテンプレートは以下のようになっているとします。
{
"id" : $util.toJson($context.result.id),
"Name" : $util.toJson($context.result.name),
"theVersion" : $util.toJson($context.result.version)
}
GraphQL レスポンスは以下のようになります。
{
"data": null,
"errors": [
{
"message": "The conditional request failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ)"
"errorType": "DynamoDB:ConditionalCheckFailedException",
...
}
]
}
また、返されたオブジェクトのフィールドすべてが他のリゾルバーによって入力され、そのミューテーションが成功した場合、オブジェクトが error
セクションに返されたときに、それらのフィールドは解決されません。
「custom」戦略に従う
Custom
戦略に従うと、 AWS AppSync DynamoDB リゾルバーは Lambda 関数を呼び出して、次に何をするかを決定します。Lambda 関数は以下のオプションのいずれかを選択します。
-
ミューテーション を
reject
する これにより、 AWS AppSync DynamoDB リゾルバーは、前のセクションで説明したように、設定された戦略が であるかのように動作しReject
、ミューテーションのエラーと DynamoDB 内のオブジェクトの現在の値を返します。 -
ミューテーション を
discard
する これにより、 AWS AppSync DynamoDB リゾルバーは条件チェックの失敗をサイレントに無視し、DynamoDB の値を返します。 -
ミューテーション を
retry
する これにより、 AWS AppSync DynamoDB リゾルバーは新しいリクエストマッピングドキュメントでミューテーションを再試行するように指示されます。
Lambda 呼び出しリクエスト
AWS AppSync DynamoDB リゾルバーは、 で指定された Lambda 関数を呼び出しますlambdaArn
。また、データソースに設定されたものと同じ service-role-arn
を使用します。呼び出しのペイロードは以下の構造を持ちます。
{
"arguments": { ... },
"requestMapping": {... },
"currentValue": { ... },
"resolver": { ... },
"identity": { ... }
}
各フィールドの定義は以下のようになります。
-
arguments
-
GraphQL ミューテーションの引数です。これは、
$context.arguments
のリクエストマッピングドキュメントで使用できる引数と同じです。 -
requestMapping
-
この処理のリクエストマッピングドキュメントです。
-
currentValue
-
DynamoDB のオブジェクトの現在値。
-
resolver
-
AWS AppSync リゾルバーに関する情報。
-
identity
-
呼び出し元に関する情報。これは、
$context.identity
のリクエストマッピングドキュメントで使用できる識別情報と同じです。
完全なペイロードの例を次に示します。
{
"arguments": {
"id": "1",
"name": "Steve",
"expectedVersion": 1
},
"requestMapping": {
"version" : "2017-02-28",
"operation" : "PutItem",
"key" : {
"id" : { "S" : "1" }
},
"attributeValues" : {
"name" : { "S" : "Steve" },
"version" : { "N" : 2 }
},
"condition" : {
"expression" : "version = :expectedVersion",
"expressionValues" : {
":expectedVersion" : { "N" : 1 }
},
"equalsIgnore": [ "version" ]
}
},
"currentValue": {
"id" : { "S" : "1" },
"name" : { "S" : "Steve" },
"version" : { "N" : 8 }
},
"resolver": {
"tableName": "People",
"awsRegion": "us-west-2",
"parentType": "Mutation",
"field": "updatePerson",
"outputType": "Person"
},
"identity": {
"accountId": "123456789012",
"sourceIp": "x.x.x.x",
"user": "AIDAAAAAAAAAAAAAAAAAA",
"userArn": "arn:aws:iam::123456789012:user/appsync"
}
}
Lambda 呼び出しレスポンス
Lambda 関数は、呼び出しペイロードを確認し、任意のビジネスロジックを適用して、 AWS の AppSync DynamoDB リゾルバーがエラーを処理する方法を決定することができます。条件チェックで検出されたエラーを処理するために、以下の 3 つのオプションが指定できます。
-
ミューテーション を
reject
する このオプションのレスポンスペイロードは次の構造を持ちます。{ "action": "reject" }
これにより、 AWS AppSync DynamoDB リゾルバーは、上記のセクションで説明されているように、設定された戦略が であるかのように動作し
Reject
、ミューテーションのエラーと DynamoDB 内のオブジェクトの現在の値を返します。 -
ミューテーション を
discard
する このオプションのレスポンスペイロードは次の構造を持ちます。{ "action": "discard" }
これにより、 AWS AppSync DynamoDB リゾルバーは条件チェックの失敗を黙って無視し、DynamoDB の値を返します。
-
ミューテーション を
retry
する このオプションのレスポンスペイロードは次の構造を持ちます。{ "action": "retry", "retryMapping": { ... } }
これにより、 AWS AppSync DynamoDB リゾルバーは新しいリクエストマッピングドキュメントでミューテーションを再試行するように指示されます。
retryMapping
セクションの構造は DynamoDB の処理によって異なり、その処理の完全なリクエストマッピングドキュメントのサブセットとなります。PutItem
の場合、retryMapping
セクションは次の構造を持ちます。attributeValues
フィールドについては、「PutItem」を参照してください。{ "attributeValues": { ... }, "condition": { "equalsIgnore" = [ ... ], "consistentRead" = true } }
UpdateItem
の場合、retryMapping
セクションは次の構造を持ちます。update
セクションについては、「UpdateItem」を参照してください。{ "update" : { "expression" : "someExpression" "expressionNames" : { "#foo" : "foo" }, "expressionValues" : { ":bar" : ... typed value } }, "condition": { "consistentRead" = true } }
DeleteItem
の場合、retryMapping
セクションは次の構造を持ちます。{ "condition": { "consistentRead" = true } }
使用する別の処理やキーを指定する方法はありません。 AWS AppSync DynamoDB リゾルバーは、同じオブジェクトに対して同じオペレーションの再試行のみを許可します。また、
condition
セクションではconditionalCheckFailedHandler
は指定できません。再試行が失敗した場合、 AWS AppSync DynamoDB リゾルバーはReject
戦略に従います。
以下は、失敗した PutItem
リクエストを処理する Lambda 関数の例です。ビジネスロジックは呼び出し元を調べます。呼び出し元が jeffTheAdmin
の場合は、リクエストを再試行して、現在 DynamoDB にある項目の version
と expectedVersion
を更新します。それ以外の場合は、ミューテーションを拒否します。
exports.handler = (event, context, callback) => {
console.log("Event: "+ JSON.stringify(event));
// Business logic goes here.
var response;
if ( event.identity.user == "jeffTheAdmin" ) {
response = {
"action" : "retry",
"retryMapping" : {
"attributeValues" : event.requestMapping.attributeValues,
"condition" : {
"expression" : event.requestMapping.condition.expression,
"expressionValues" : event.requestMapping.condition.expressionValues
}
}
}
response.retryMapping.attributeValues.version = { "N" : event.currentValue.version.N + 1 }
response.retryMapping.condition.expressionValues[':expectedVersion'] = event.currentValue.version
} else {
response = { "action" : "reject" }
}
console.log("Response: "+ JSON.stringify(response))
callback(null, response)
};