本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
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-28 到 2018-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
區塊中。