選取您的 Cookie 偏好設定

我們使用提供自身網站和服務所需的基本 Cookie 和類似工具。我們使用效能 Cookie 收集匿名統計資料,以便了解客戶如何使用我們的網站並進行改進。基本 Cookie 無法停用,但可以按一下「自訂」或「拒絕」以拒絕效能 Cookie。

如果您同意,AWS 與經核准的第三方也會使用 Cookie 提供實用的網站功能、記住您的偏好設定,並顯示相關內容,包括相關廣告。若要接受或拒絕所有非必要 Cookie,請按一下「接受」或「拒絕」。若要進行更詳細的選擇,請按一下「自訂」。

條件表達式

焦點模式
條件表達式 - AWS AppSync GraphQL

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

當您使用 PutItemUpdateItem和 DynamoDB 操作來變更 DeleteItem DynamoDB 中的物件時,您可以選擇指定條件表達式,以根據在執行操作之前已在 DynamoDB 中建立的物件狀態來控制請求是否成功。

The AWS AppSync DynamoDB 函數允許在 PutItemUpdateItemDeleteItem請求物件中指定條件表達式,以及如果條件失敗且未更新物件時要遵循的策略。

範例 1

下列PutItem請求物件沒有條件表達式。因此,即使具有相同索引鍵的項目已存在,也會將項目放入 DynamoDB,藉此覆寫現有項目。

import { util } from '@aws-appsync/utils'; export function request(ctx) { const { foo, bar, ...values} = ctx.args return { operation: 'PutItem', key: util.dynamodb.toMapValues({foo, bar}), attributeValues: util.dynamodb.toMapValues(values), }; }

範例 2

下列PutItem物件確實有條件表達式,只有在 DynamoDB 中不存在具有相同索引鍵的項目時,才會允許操作成功。

import { util } from '@aws-appsync/utils'; export function request(ctx) { const { foo, bar, ...values} = ctx.args return { operation: 'PutItem', key: util.dynamodb.toMapValues({foo, bar}), attributeValues: util.dynamodb.toMapValues(values), condition: { expression: "attribute_not_exists(id)" } }; }

根據預設,如果條件檢查失敗, AWS AppSync DynamoDB 函數會提供變動的錯誤。

不過, AWS AppSync DynamoDB 函數提供一些額外的功能,以協助開發人員處理一些常見的邊緣案例:

  • If AWS AppSync DynamoDB 函數可以判斷 DynamoDB 中的目前值是否符合所需的結果,它會將操作視為成功。

  • 您可以設定函數來叫用自訂 Lambda 函數,以決定 AWS AppSync DynamoDB 函數應如何處理失敗,而不是傳回錯誤。

這些會在處理條件檢查失敗一節中詳細說明。

如需 DynamoDB 條件表達式的詳細資訊,請參閱 DynamoDB ConditionExpressions 文件

指定條件

PutItemUpdateItemDeleteItem請求物件都允許指定選用condition區段。若省略,則不會有條件檢查。若指定,條件必須為 true,操作才會成功。

condition 區段的結構如下:

type ConditionCheckExpression = { expression: string; expressionNames?: { [key: string]: string}; expressionValues?: { [key: string]: any}; equalsIgnore?: string[]; consistentRead?: boolean; conditionalCheckFailedHandler?: { strategy: 'Custom' | 'Reject'; lambdaArn?: string; }; };

下列欄位指定條件:

expression

更新表達式本身。如需如何編寫條件表達式的詳細資訊,請參閱 DynamoDB ConditionExpressions 文件。必須指定此欄位。

expressionNames

表達式屬性名稱預留位置的替代,形式為索引鍵值對。索引鍵對應至表達式中使用的名稱預留位置,且值必須是對應於 DynamoDB 中項目屬性名稱的字串。此欄位為選用的,應只能填入於表達式中所用表達式屬性名稱預留位置的替代。

expressionValues

表達式屬性值預留位置的替代,形式為索引值對。鍵對應用於表達式的值預留位置,值必須是類型值。如需如何指定「輸入值」的詳細資訊,請參閱類型系統 (請求映射)。此必須指定。此欄位為選用的,應只能填入用於表達式中表達式屬性值預留位置的替代。

其餘欄位會告知 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

在將 DynamoDB 中的目前值與預期結果進行比較之後, AWS AppSync DynamoDB 函數採用的策略。 DynamoDB 此欄位為必填,且採用下列可能值:

Reject

變動失敗,且錯誤會新增至 GraphQL 回應。

Custom

The AWS AppSync DynamoDB 函數會叫用自訂 Lambda 函數,以決定如何處理條件檢查失敗。當 strategy 設定為 CustomlambdaArn 欄位必須包含要叫用 Lambda 函數的 ARN。

lambdaArn

要叫用之 Lambda 函數的 ARN,其決定 AWS AppSync DynamoDB 函數應如何處理條件檢查失敗。只有在 strategy 設定為 Custom 時,此欄位才必須指定。如需如何使用此功能的詳細資訊,請參閱處理條件檢查失敗

處理條件檢查失敗

當條件檢查失敗時, AWS AppSync DynamoDB 函數可以使用 util.appendError公用程式傳遞 變動的錯誤和物件的目前值。不過, AWS AppSync DynamoDB 函數提供一些額外的功能,以協助開發人員處理一些常見的邊緣案例:

  • If AWS AppSync DynamoDB 函數可以判斷 DynamoDB 中的目前值是否符合所需的結果,它會將操作視為成功。

  • 您可以設定函數來叫用自訂 Lambda 函數,以決定 AWS AppSync DynamoDB 函數應如何處理失敗,而不是傳回錯誤。

此程序的流程圖為:

檢查所需結果

當條件檢查失敗時, AWS AppSync DynamoDB 函數會執行 GetItem DynamoDB 請求,從 DynamoDB 取得項目的目前值。在預設情況下,它會使用強式一致性讀取,但這可使用 condition 區塊中的 consistentRead 欄位來設定,並和預期結果進行比較:

  • 對於 PutItem操作, AWS AppSync DynamoDB 函數會將目前的值與其嘗試寫入的值進行比較,排除equalsIgnore比較中列出的任何屬性。如果項目相同,它會將操作視為成功,並傳回從 DynamoDB 擷取的項目。否則,其將按照設定的策略。

    例如,如果PutItem請求物件看起來如下所示:

    import { util } from '@aws-appsync/utils'; export function request(ctx) { const { id, name, version} = ctx.args return { operation: 'PutItem', key: util.dynamodb.toMapValues({foo, bar}), attributeValues: util.dynamodb.toMapValues({ name, version: version+1 }), condition: { expression: "version = :expectedVersion", expressionValues: util.dynamodb.toMapValues({':expectedVersion': version}), equalsIgnore: ['version'] } }; }

    而目前在 DynamoDB 中的項目外觀如下:

    { "id" : { "S" : "1" }, "name" : { "S" : "Steve" }, "version" : { "N" : 8 } }

    The AWS AppSync DynamoDB 函數會將嘗試寫入的項目與目前值進行比較,查看唯一差異是 version 欄位,但因為它設定為忽略 version 欄位,它會將操作視為成功,並傳回從 DynamoDB 擷取的項目。

  • 對於 DeleteItem操作, AWS AppSync DynamoDB 函數會檢查以確認項目已從 DynamoDB 傳回。如果沒有項目傳回,則操作視為成功。否則,其將按照設定的策略。

  • 對於 UpdateItem操作, AWS AppSync DynamoDB 函數沒有足夠的資訊來判斷目前 DynamoDB 中的項目是否符合預期結果,因此遵循設定的策略。

如果 DynamoDB 中物件的目前狀態與預期結果不同, AWS AppSync DynamoDB 函數會遵循已設定的策略,以拒絕變動或叫用 Lambda 函數來決定接下來要做什麼。

遵循「拒絕」策略

遵循Reject策略時, AWS AppSync DynamoDB 函數會傳回變動的錯誤。

例如,假設變動要求如下:

mutation { updatePerson(id: 1, name: "Steve", expectedVersion: 1) { Name theVersion } }

如果從 DynamoDB 傳回的項目如下所示:

{ "id" : { "S" : "1" }, "name" : { "S" : "Steve" }, "version" : { "N" : 8 } }

而且函數回應處理常式如下所示:

import { util } from '@aws-appsync/utils'; export function response(ctx) { const { version, ...values } = ctx.result; const result = { ...values, theVersion: version }; if (ctx.error) { if (error) { return util.appendError(error.message, error.type, result, null); } } return result }

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策略時, AWS AppSync DynamoDB 函數會叫用 Lambda 函數來決定接下來要做什麼。Lambda 函數會選擇下列其中一個選項:

  • reject 變動。這可讓 AWS AppSync DynamoDB 函數表現得好像已設定的策略是 Reject,傳回 DynamoDB 中物件的變動錯誤和目前值,如上一節所述。

  • discard 變動。這可讓 AWS AppSync DynamoDB 函數以無提示方式忽略條件檢查失敗,並在 DynamoDB 中傳回值。

  • retry 變動。這會告知 AWS AppSync DynamoDB 函數使用新的請求物件重試變動。

Lambda 叫用要求

The 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 函數應如何處理失敗。處理條件檢查失敗有三個選項:

  • reject 變動。此選項的回應承載必須具有此架構:

    { "action": "reject" }

    這可讓 AWS AppSync DynamoDB 函數表現得好像設定的策略是 Reject,傳回 DynamoDB 中物件的變動錯誤和目前值,如上節所述。

  • discard 變動。此選項的回應承載必須具有此架構:

    { "action": "discard" }

    這可讓 AWS AppSync DynamoDB 函數以無提示方式忽略條件檢查失敗,並在 DynamoDB 中傳回 值。

  • retry 變動。此選項的回應承載必須具有此架構:

    { "action": "retry", "retryMapping": { ... } }

    這會告知 AWS AppSync DynamoDB 函數使用新的請求物件重試變動。retryMapping 區段的結構取決於 DynamoDB 操作,並且是該操作完整請求物件的子集。

    若是 PutItemretryMapping 區段的結構如下。如需 attributeValues 欄位的描述,請參閱 PutItem

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

    若是 UpdateItemretryMapping 區段的結構如下。如需 update 區段的描述,請參閱 UpdateItem

    { "update" : { "expression" : "someExpression" "expressionNames" : { "#foo" : "foo" }, "expressionValues" : { ":bar" : ... typed value } }, "condition": { "consistentRead" = true } }

    若是 DeleteItemretryMapping 區段的結構如下。

    { "condition": { "consistentRead" = true } }

    無法指定使用不同的操作或索引鍵。 AWS AppSync DynamoDB 函數僅允許對相同物件進行相同操作的重試。此外,condition 區段不允許指定 conditionalCheckFailedHandler。如果重試失敗, AWS AppSync DynamoDB 函數會遵循 Reject策略。

此為 Lambda 函數處理失敗 PutItem 要求的範例。商業邏輯的重點是發起人為何。如果是由 提出jeffTheAdmin,則會重試請求,expectedVersion並從目前 DynamoDB 中的項目更新 version和 。否則,它會拒絕變動。

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) };
隱私權網站條款Cookie 偏好設定
© 2025, Amazon Web Services, Inc.或其附屬公司。保留所有權利。