View a markdown version of this page

Amazon AppSync 解析器映射模板更新日志 - Amazon AppSync GraphQL
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)。

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

Amazon AppSync 解析器映射模板更新日志

注意

我们现在主要支持 APPSYNC_JS 运行时系统及其文档。请考虑使用 APPSYNC_JS 运行时系统和此处的指南。

解析器和函数映射模板已版本化。映射模板版本(例如 2018-05-29)指示以下内容:

  • 请求模板提供的数据来源请求配置的预期形状

  • 请求映射模板和响应映射模板的执行行为

版本使用 YYYY-MM-DD格式表示,较晚的日期对应于较新的版本。该页面列出了 Amazon AppSync中当前支持的映射模板版本之间的差异。

每个版本矩阵的数据来源操作可用性

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

Amazon Lambda 调用

支持

是

Amazon Lambda BatchInvoke

是

是

None Datasource

支持

是

Amazon OpenSearch GET

支持

是

Amazon OpenSearch POST

支持

是

亚马逊 P OpenSearch UT

支持

是

亚马逊 OpenSearch 删除

支持

是

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 字段更新为新版本。

例如,要更新 Amazon 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 块中。