

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# 条件式
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-condition-expressions"></a>

`PutItem`、`UpdateItem`、および `DeleteItem` の各 DynamoDB 処理を使用して DynamoDB のオブジェクトをミューテーションする場合、オプションで、処理を実行する前に、DynamoDB にある既存のオブジェクトの状態に基づいてリクエストが成功するかどうかを制御する条件式を指定することができます。

 AWS AppSync DynamoDB リゾルバーでは`PutItem`、、`UpdateItem`、および `DeleteItem` リクエストマッピングドキュメントで条件式を指定できます。また、条件が失敗し、オブジェクトが更新されなかった場合に従う戦略も指定できます。

## 例 1
<a name="id19"></a>

以下の `PutItem` マッピングドキュメントには条件式がありません。その結果、同じキーに対応する項目がすでにある場合でも、項目は DynamoDB に挿入され、それにより既存の項目が上書きされます。

```
{
   "version" : "2017-02-28",
   "operation" : "PutItem",
   "key" : {
      "id" : { "S" : "1" }
   }
}
```

## 例 2
<a name="id20"></a>

次の `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 リゾルバーが障害を処理する方法を決定するようにリゾルバーを設定できます。

これらの詳細については、「[条件チェックでのエラーを処理する](#aws-appsync-resolver-mapping-template-reference-dynamodb-condition-handling)」セクションを参照してください。

DynamoDB の条件式の詳細については、「[DynamoDB ConditionExpressions のドキュメント](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html)」を参照してください。

## 条件を指定する
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-condition-specification"></a>

`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 のドキュメント](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html)を参照してください。このフィールドの指定は必須です。

** `expressionNames` **  
式の属性名のプレースホルダーを示します。キー - 値のペアの形式になります。キーは *expression* で使用される名前のプレースホルダーに対応し、値は DynamoDB の項目の属性名と一致する文字列でなければなりません。このフィールドはオプションであり、*expression* で使用される式の属性名のプレースホルダーのみを入力します。

** `expressionValues` **  
式の属性値のプレースホルダーを示します。キー - 値のペアの形式になります。キーは expression で使用される値のプレースホルダーに対応し、値は型付き値でなければなりません。「型付き値」を指定する方法の詳細については、「[型システム (リクエストマッピング)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)」を参照してください。この指定は必須です。このフィールドはオプションであり、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 の現在の値を予想される結果と比較した後に、条件チェックの失敗を処理する方法を指定できます。このセクションはオプションです。省略した場合、デフォルトの処理は `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-resolver-mapping-template-reference-dynamodb-condition-handling)」を参照してください。

## 条件チェックでのエラーを処理する
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-condition-handling"></a>

デフォルトでは、条件チェックが失敗すると、 AWS AppSync DynamoDB リゾルバーはミューテーションのエラーと DynamoDB 内のオブジェクトの現在の値を返します。ただし、 AWS AppSync DynamoDB リゾルバーには、開発者が一般的なエッジケースを処理するのに役立ついくつかの追加機能があります。
+  AWS AppSync DynamoDB リゾルバーは、DynamoDB の現在の値が目的の結果と一致すると判断できる場合、オペレーションが成功したかのように処理します。
+ エラーを返す代わりに、カスタム Lambda 関数を呼び出して AWS AppSync DynamoDB リゾルバーが障害を処理する方法を決定するようにリゾルバーを設定できます。

このプロセスのフローチャートは次のとおりです。

![\[Flowchart showing process for transforming requests with mutation attempts and value checks.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/DynamoDB-condition-check-failure-handling.png)


### 必要な結果をチェックする
<a name="checking-for-the-desired-result"></a>

条件チェックが失敗すると、 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」の戦略に従う
<a name="following-the-reject-strategy"></a>

`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」戦略に従う
<a name="following-the-custom-strategy"></a>

`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](aws-appsync-resolver-mapping-template-reference-dynamodb-putitem.md)」を参照してください。

  ```
  {
      "attributeValues": { ... },
      "condition": {
          "equalsIgnore" = [ ... ],
          "consistentRead" = true
      }
  }
  ```

  `UpdateItem` の場合、`retryMapping` セクションは次の構造を持ちます。`update` セクションについては、「[UpdateItem](aws-appsync-resolver-mapping-template-reference-dynamodb-updateitem.md)」を参照してください。

  ```
  {
      "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)
};
```