조건 표현식 - AWS AppSync

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

조건 표현식

DynamoDB에서 PutItem, UpdateItemDeleteItem DynamoDB 작업을 사용하여 객체를 변경하는 경우, 작업을 수행하기 전에 DynamoDB에 이미 있는 객체의 상태를 기준으로 요청에 성공할지 여부를 제어하는 조건 표현식을 선택적으로 지정할 수 있습니다.

AWS AppSync DynamoDB 해석기를 사용하면 PutItem, UpdateItemDeleteItem 요청 매핑 문서에 조건 표현식을 지정할 수 있으며, 조건이 실패하고 객체가 업데이트되지 않은 경우 따라야 할 전략도 지정할 수 있습니다.

예 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 해석기는 GraphQL 응답 error 섹션의 data 필드에 돌연변이 및 DynamoDB에 있는 객체의 현재 값에 대한 오류를 반환합니다. 그러나 AWS AppSync DynamoDB 해석기는 개발자가 몇 가지 일반적인 엣지 사례를 처리하는 데 도움이 되는 몇 가지 추가 기능을 제공합니다.

  • AWS AppSync DynamoDB 해석기가 DynamoDB의 현재 값이 원하는 결과와 일치하는지 확인할 수 있는 경우 작업을 성공한 것처럼 취급합니다.

  • 오류를 반환하는 대신 사용자 지정 Lambda 함수를 호출하여 AWS AppSync DynamoDB 해석기가 오류를 처리하는 방법을 결정하도록 해석기를 구성할 수 있습니다.

이러한 내용은 조건 확인 실패 처리 단원에 자세히 설명되어 있습니다.

DynamoDB 조건 표현식에 대한 자세한 내용은 DynamoDB ConditionExpressions 설명서 섹션을 참조하세요.

조건 지정

PutItem, UpdateItemDeleteItem 요청 매핑 문서 모두에서 선택적 condition 섹션을 지정할 수 있습니다. 이 섹션을 지정하지 않으면 조건 검사가 수행되지 않습니다. 지정한 경우, 해당 조건을 충족해야 작업이 성공합니다.

condition 섹션의 구조는 다음과 같습니다.

"condition" : { "expression" : "someExpression" "expressionNames" : { "#foo" : "foo" }, "expressionValues" : { ":bar" : ... typed value }, "equalsIgnore" : [ "version" ], "consistentRead" : true, "conditionalCheckFailedHandler" : { "strategy" : "Custom", "lambdaArn" : "arn:..." } }

조건을 지정하는 필드는 다음과 같습니다.

expression

업데이트 표현식 자체. 조건 표현식을 작성하는 방법에 대한 자세한 내용은 DynamoDB ConditionExpressions 설명서 섹션을 참조하세요. 이 필드는 지정되어 있어야 합니다.

expressionNames

표현식 속성 name 자리 표시자의 대체 항목으로, 키-값 페어의 형식으로 표시됩니다. 키는 expression에 사용된 name 자리 표시자에 해당하고 값은 DynamoDB에 있는 항목의 속성 이름에 해당하는 문자열이어야 합니다. 이 필드는 선택 사항으로, expression에 사용된 표현식 속성인 name 자리 표시자의 대체 항목으로만 채워져야 합니다.

expressionValues

표현식 속성 value 자리 표시자의 대체 항목으로, 키-값 페어의 형식으로 표시됩니다. 키는 expression에 사용되는 value 자리 표시자에 해당하고 값은 입력된 값이어야 합니다. "입력된 값"을 지정하는 방법에 대한 자세한 내용은 형식 시스템(요청 매핑)을 참조하십시오. 입력된 값은 지정되어 있어야 합니다. 이 필드는 선택 사항으로, expression에 사용된 표현식 속성인 value 자리 표시자의 대체 항목으로만 채워져야 합니다.

나머지 필드는 AWS AppSync DynamoDB 해석기에 조건 확인 실패를 처리하는 방법을 알려줍니다.

equalsIgnore

PutItem 작업을 사용할 때 조건 확인이 실패하면 AWS AppSync DynamoDB 해석기는 현재 DynamoDB에 있는 항목을 쓰려고 시도한 항목과 비교합니다. 이러한 두 항목이 동일하면 해석기에서는 해당 작업을 마치 성공한 것처럼 간주합니다. equalsIgnore 필드를 사용하여 해당 비교를 수행할 때 무시 AWS AppSync 해야 하는 속성 목록을 지정할 수 있습니다. 예를 들어, version 속성만 차이가 나는 경우에는 해당 작업을 성공한 작업으로 취급합니다. 이 필드는 선택 사항입니다.

consistentRead

조건 확인에 실패하면 는 매우 일관된 읽기를 사용하여 DynamoDB에서 항목의 현재 값을 AWS AppSync 가져옵니다. 이 필드를 사용하여 AWS AppSync DynamoDB 해석기에 최종적으로 일관된 읽기를 대신 사용하도록 지시할 수 있습니다. 이 필드는 선택 사항으로, 기본값은 true입니다.

conditionalCheckFailedHandler

이 섹션에서는 AWS AppSync DynamoDB의 현재 값을 예상 결과와 비교한 후 DynamoDB 해석기가 조건 확인 실패를 처리하는 방법을 지정할 수 있습니다. 이 섹션은 선택 사항입니다. 방법을 지정하지 않으면 Reject 전략이 기본값으로 지정됩니다.

strategy

AWS AppSync DynamoDB 해석기가 DynamoDB의 현재 값을 예상 결과와 비교한 후 수행하는 전략입니다. 이 필드는 필수 필드로, 다음과 같은 두 가지 값을 가질 수 있습니다.

Reject

변형에 실패하고, GraphQL 응답의 error 섹션에 있는 data 필드에 DynamoDB에 있는 객체의 현재 값과 변형에 대한 오류를 반환합니다.

Custom

AWS AppSync DynamoDB 해석기는 사용자 지정 Lambda 함수를 호출하여 조건 확인 실패를 처리하는 방법을 결정합니다. strategy 가 로 설정된 경우 Custom lambdaArn 필드에는 호출할 Lambda 함수ARN의 가 포함되어야 합니다.

lambdaArn

AWS AppSync DynamoDB 해석기가 조건 확인 실패ARN를 처리하는 방법을 결정하는 호출을 위한 Lambda 함수의 . 이 필드는 strategyCustom으로 설정한 경우에만 지정해야 합니다. 이 기능을 사용하는 방법에 대한 자세한 내용은 조건 검사 실패 처리를 참조하십시오.

조건 검사 실패 처리

기본적으로 조건 확인이 실패하면 AWS AppSync DynamoDB 해석기는 GraphQL 응답 error 섹션의 data 필드에 돌연변이 및 DynamoDB에 있는 객체의 현재 값에 대한 오류를 반환합니다. 그러나 AWS AppSync DynamoDB 해석기는 개발자가 몇 가지 일반적인 엣지 사례를 처리하는 데 도움이 되는 몇 가지 추가 기능을 제공합니다.

  • AWS AppSync DynamoDB 해석기가 DynamoDB의 현재 값이 원하는 결과와 일치하는지 확인할 수 있는 경우 작업을 성공한 것처럼 취급합니다.

  • 오류를 반환하는 대신 사용자 지정 Lambda 함수를 호출하여 AWS AppSync DynamoDB 해석기가 오류를 처리하는 방법을 결정하도록 해석기를 구성할 수 있습니다.

이 프로세스의 흐름 차트입니다.

원하는 결과 확인

조건 확인에 실패하면 AWS AppSync DynamoDB 해석기는 GetItem DynamoDB 요청을 수행하여 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 해석기는 돌연변이에 대한 오류를 반환하고 DynamoDB에서 객체의 현재 값도 GraphQL 응답 error 섹션의 data 필드에 반환됩니다. 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", "data": { "Name": "Steve", "theVersion": 8 }, ... } ] }

반환된 객체의 필드를 다른 해석기가 채우고 변형에 성공했는데 이 객체가 error 섹션에서 반환되면 반환된 객체의 필드가 확인되지 않습니다.

'Custom' 전략 따르기

Custom 전략을 따를 때 AWS AppSync DynamoDB 해석기는 Lambda 함수를 호출하여 다음에 수행할 작업을 결정합니다. Lambda 함수는 다음 옵션 중 하나를 선택합니다.

  • 변형 reject. 이는 AWS AppSync DynamoDB 해석기에 구성된 전략이 인 것처럼 작동하도록 지시하여 이전 섹션에 설명된 대로 DynamoDB에서 돌연변이 및 객체의 현재 값에 대한 오류를 Reject반환합니다.

  • 변형 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 해석기에 구성된 전략이 인 것처럼 동작하여 DynamoDB 에서 변형 및 객체의 현재 값에 대한 오류를 Reject반환하도록 지시합니다.

  • 변형 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에 있는 항목에서 versionexpectedVersion을 업데이트합니다. 그렇지 않으면 변형을 거부합니다.

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) };