本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
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 |
是 |
是 |
亚马逊 OpenSearch GET |
是 |
是 |
亚马逊 OpenSearch POST |
是 |
是 |
亚马逊 OpenSearch PUT |
是 |
是 |
亚马逊 OpenSearch DELETE |
是 |
是 |
亚马逊 OpenSearch GET |
是 |
是 |
DynamoDB GetItem |
是 |
是 |
DynamoDB Scan |
是 |
是 |
DynamoDB Query |
是 |
是 |
DynamoDB DeleteItem |
是 |
是 |
DynamoDB PutItem |
是 |
是 |
DynamoDB BatchGetItem |
否 |
是 |
DynamoDB BatchPutItem |
否 |
是 |
DynamoDB BatchDeleteItem |
否 |
是 |
HTTP |
否 |
是 |
亚马逊 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
块中。
Reasoning
-
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 保留相同的执行行为
在某些情况下,在执行 2018-05-29 版本的模板时,可以保留与 2017-02-28 版本相同的执行行为。
示例: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)
现在,您有责任处理错误,我们选择使用从 DynamoDB 返回的 $util.error()
来引发同一错误。您可以调整此代码段以将映射模板转换为 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
块中。