AWS AppSync 解析器映射範本變更日誌 - AWS AppSync

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

AWS AppSync 解析器映射範本變更日誌

注意

我們現在主要支援 APPSYNC_JS 執行期及其文件。請考慮在此處使用 APPSYNC_JS 執行期及其指南

解析程式和函數映射範本已採取版本控制。映射範本版本,例如 2018-05-29) 規定了以下內容:

  • 請求範本所提供資料來源請求組態的預期形狀

  • 請求映射範本和回應映射範本的執行行為

版本使用 YYYY-MM-DD 格式表示,較晚的日期對應至較新的版本。此頁面列出目前在 中支援的映射範本版本之間的差異 AWS AppSync。

每種版本陣列的可用資料來源操作

支援的操作/版本 2017-02-28 2018-05-29

AWS Lambda 叫用

AWS Lambda BatchInvoke

None Datasource

Amazon OpenSearch GET

Amazon OpenSearch POST

Amazon OpenSearch PUT

Amazon OpenSearch DELETE

Amazon OpenSearch GET

DynamoDB GetItem

DynamoDB Scan

DynamoDB Query

DynamoDB DeleteItem

DynamoDB PutItem

DynamoDB BatchGetItem

DynamoDB BatchPutItem

DynamoDB BatchDeleteItem

HTTP

Amazon RDS

注意:函數目前僅支援 2018-05-29 版本。

變更單位解析程式映射範本的版本

對於單位解析程式,版本會指定為要求映射範本的內容部分。若要更新版本,只要直接將 version 欄位更新成新版本。

例如,若要更新 AWS Lambda 範本上的版本:

{ "version": "2017-02-28", "operation": "Invoke", "payload": { "field": "getPost", "arguments": $utils.toJson($context.arguments) } }

您需要將 2017-02-28 的版本欄位更新成 2018-05-29,如下所示:

{ "version": "2018-05-29", ## Note the version "operation": "Invoke", "payload": { "field": "getPost", "arguments": $utils.toJson($context.arguments) } }

變更函數的版本

對於函數,版本會透過函數物件上的 functionVersion 欄位指定。若要更新版本,可直接更新 functionVersion注意:目前只有 2018-05-29 支援函數。

以下是更新現有函數版本的CLI命令範例:

aws appsync update-function \ --api-id REPLACE_WITH_API_ID \ --function-id REPLACE_WITH_FUNCTION_ID \ --data-source-name "PostTable" \ --function-version "2018-05-29" \ --request-mapping-template "{...}" \ --response-mapping-template "\$util.toJson(\$ctx.result)"

注意:建議省略要求映射範本的版本欄位,因為其不會獲得接收。如果您在函數要求映射範本內指定版本,functionVersion 欄位的值將覆寫此版本值。

2018-05-29

行為變更

  • 如果資料來源呼叫結果是 null,回應映射範本將會執行。

  • 如果資料來源呼叫產生錯誤,您現在要負責處理錯誤,而回應映射範本評估結果將一律置放在 GraphQL 回應 data 區塊中。

推理

  • null 呼叫結果具有意義,而且在某些應用程式使用案例中,我們可能希望以自訂方式處理 null 結果。例如,應用程式可以檢查記錄是否存在於 Amazon DynamoDB 資料表,以便執行一些授權檢查。在這種情況下,null 呼叫結果就能表示使用者應未獲得授權。執行回應映射範本現在會提供引發關於未經授權錯誤的能力。此行為可為API設計者提供更大的控制。

假設我們使用下列的回應映射範本:

$util.toJson($ctx.result)

過去使用 2017-02-28 時,如果 $ctx.result 傳回 Null,回應映射範本將不會執行。現在使用 2018-05-29 時,我們可以處理此案例。例如,我們可以選擇引發授權錯誤如下:

# throw an unauthorized error if the result is null #if ( $util.isNull($ctx.result) ) $util.unauthorized() #end $util.toJson($ctx.result)

注意:從資料來源發出的錯誤有時並不嚴重,或甚至早有預期,這說明了為什麼回應映射範本應該可靈活處理呼叫錯誤,並決定是否予以忽略、重新引發,或是擲出不同的錯誤。

假設我們使用下列的回應映射範本:

$util.toJson($ctx.result)

過去使用 2017-02-28 時,如果發生呼叫錯誤,回應映射範本將會進行評估,而且結果會自動放置在 GraphQL 回應的 errors 區塊。現在使用 2018-05-29 時,我們可以選擇如何處理錯誤、重新引發錯誤、引發不同的錯誤,或在傳回資料時附加該錯誤。

再次引發呼叫錯誤

使用下列回應範本時,我們會引發資料來源發出的相同錯誤。

#if ( $ctx.error ) $util.error($ctx.error.message, $ctx.error.type) #end $util.toJson($ctx.result)

如果發生呼叫錯誤 (例如,$ctx.error 存在時) 回應看起來將如下所示:

{ "data": { "getPost": null }, "errors": [ { "path": [ "getPost" ], "errorType": "DynamoDB:ConditionalCheckFailedException", "message": "Conditional check failed exception...", "locations": [ { "line": 5, "column": 5 } ] } ] }

引發不同的錯誤

使用下列回應範本時,我們會在處理資料來源發出錯誤之後引發自訂的錯誤。

#if ( $ctx.error ) #if ( $ctx.error.type.equals("ConditionalCheckFailedException") ) ## we choose here to change the type and message of the error for ConditionalCheckFailedExceptions $util.error("Error while updating the post, try again. Error: $ctx.error.message", "UpdateError") #else $util.error($ctx.error.message, $ctx.error.type) #end #end $util.toJson($ctx.result)

如果發生呼叫錯誤 (例如,$ctx.error 存在時) 回應看起來將如下所示:

{ "data": { "getPost": null }, "errors": [ { "path": [ "getPost" ], "errorType": "UpdateError", "message": "Error while updating the post, try again. Error: Conditional check failed exception...", "locations": [ { "line": 5, "column": 5 } ] } ] }

附加錯誤至傳回資料

使用下列回應範本時,當透過回應傳回資料時,我們會同時附加由資料來源發出的相同錯誤。這也稱為部分回應。

#if ( $ctx.error ) $util.appendError($ctx.error.message, $ctx.error.type) #set($defaultPost = {id: "1", title: 'default post'}) $util.toJson($defaultPost) #else $util.toJson($ctx.result) #end

如果發生呼叫錯誤 (例如,$ctx.error 存在時) 回應看起來將如下所示:

{ "data": { "getPost": { "id": "1", "title: "A post" } }, "errors": [ { "path": [ "getPost" ], "errorType": "ConditionalCheckFailedException", "message": "Conditional check failed exception...", "locations": [ { "line": 5, "column": 5 } ] } ] }

2017-02-28 遷移到 2018-05-29

2017-02-28 遷移到 2018-05-29 的過程相當簡單。變更在解析程式要求映射範本或函數版本物件上的版本欄位。不過,請注意,2018-05-29 的執行行為不同於 2017-02-28,其中變更已概述於此處

保留 2017-02-282018-05-29 的相同執行行為

在某些情況下,在執行 2017-02-28 版本化範本時,可以保留與 2018-05-29 版本相同的執行行為。

範例:DynamoDB PutItem

根據下列 2017-02-28 DynamoDB PutItem 請求範本:

{ "version" : "2017-02-28", "operation" : "PutItem", "key": { "foo" : ... typed value, "bar" : ... typed value }, "attributeValues" : { "baz" : ... typed value }, "condition" : { ... } }

並使用下列回應範本:

$util.toJson($ctx.result)

遷移到 2018-05-29,這些範本變更如下:

{ "version" : "2018-05-29", ## Note the new 2018-05-29 version "operation" : "PutItem", "key": { "foo" : ... typed value, "bar" : ... typed value }, "attributeValues" : { "baz" : ... typed value }, "condition" : { ... } }

而且回應範本變更如下:

## If there is a datasource invocation error, we choose to raise the same error ## the field data will be set to null. #if($ctx.error) $util.error($ctx.error.message, $ctx.error.type, $ctx.result) #end ## If the data source invocation is null, we return null. #if($util.isNull($ctx.result)) #return #end $util.toJson($ctx.result)

現在,錯誤處理將由您負責,我們選擇使用 $util.error() 引發從 DynamoDB 傳回的相同錯誤。您可以調整這個片段,將您的映射範本轉換成 2018-05-29,請注意,如果您使用不同的回應範本,則您必須處理執行行為變更。

範例:DynamoDB GetItem

根據下列 2017-02-28 DynamoDB GetItem 請求範本:

{ "version" : "2017-02-28", "operation" : "GetItem", "key" : { "foo" : ... typed value, "bar" : ... typed value }, "consistentRead" : true }

並使用下列回應範本:

## map table attribute postId to field Post.id $util.qr($ctx.result.put("id", $ctx.result.get("postId"))) $util.toJson($ctx.result)

遷移到 2018-05-29,這些範本變更如下:

{ "version" : "2018-05-29", ## Note the new 2018-05-29 version "operation" : "GetItem", "key" : { "foo" : ... typed value, "bar" : ... typed value }, "consistentRead" : true }

而且回應範本變更如下:

## If there is a datasource invocation error, we choose to raise the same error #if($ctx.error) $util.error($ctx.error.message, $ctx.error.type) #end ## If the data source invocation is null, we return null. #if($util.isNull($ctx.result)) #return #end ## map table attribute postId to field Post.id $util.qr($ctx.result.put("id", $ctx.result.get("postId"))) $util.toJson($ctx.result)

使用 2017-02-28 版本時,如果資料來源呼叫為 null,表示 DynamoDB 資料表中沒有符合索引鍵的項目,而回應映射範本將不會執行。這種做法應該適用於大部分的案例,但是如果您希望 $ctx.result 不要是 null,現在您必須負責處理該案例。

2017-02-28

特性

  • 如果資料來源呼叫結果是 null,回應映射範本將不會執行。

  • 如果資料來源呼叫產生錯誤,您現在要負責處理錯誤,而回應映射範本會執行,且評估結果會置放在 GraphQL 回應 errors.data 區塊中。