本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
Amazon AppSync 解析器映射模板概述
注意
我们现在主要支持 APPSYNC _JS 运行时及其文档。请考虑在此处使用 APPSYNC _JS 运行时及其指南。
Amazon AppSync 允许您通过对资源执行操作来响应 GraphQL 请求。对于您希望运行查询或变更的每个 GraphQL 字段,必须附加解析器才能与数据来源通信。通常,通信是通过数据来源特有的参数或操作完成的。
解析器是 GraphQL 和数据来源之间的连接器。它们讲述 Amazon AppSync 如何将传入的 GraphQL 请求转换为后端数据源的指令,以及如何将来自该数据源的响应转换回 GraphQL 响应。它们是用 Apache Velocity 模板语言 (VTL)
有两种类型的解析器利用映射模板的方式略有不同: Amazon AppSync
-
单位解析器
-
管道解析器
单位解析器
单位解析器是独立的实体,仅包含请求和响应模板。将它们用于简单、单一的操作(例如,列出来自单个数据来源的项目)。
-
请求模板:在解析 GraphQL 操作后获取传入请求,并将其转换为选定数据来源操作的请求配置。
-
响应模板:解释来自数据来源的响应,并将其映射到 GraphQL 字段输出类型的形状。
管道解析器
管道解析器包含一个或多个按顺序执行的函数。每个函数包含一个请求模板和一个响应模板。管道解析器还具有一个之前 模板和一个之后 模板,它们位于模板包含的一系列函数两侧。之后 模板映射到 GraphQL 字段输出类型。管道解析器与单位解析器的不同之处在于响应模板映射输出的方式。管道解析器可以映射到所需的任何输出,包括另一个函数的输入或管道解析器的之后 模板。
管道解析器函数 允许您编写可在架构中的多个解析器之间重复使用的通用逻辑。函数直接附加到数据来源,并且像单位解析器一样,包含相同的请求和响应映射模板格式。
下图说明了左侧单位解析器和右侧管道解析器的流程。
管道解析器包含单位解析器支持的功能的超集以及更多功能,但代价是稍微复杂一些。
管道解析器剖析
管道解析器由之前映射模板、之后映射模板和一组函数组成。每个函数具有对数据来源执行的请求映射模板和响应映射模板。由于管道解析器将执行委托给函数列表,因此它不会链接到任何数据来源。单位解析器和函数是对数据来源执行操作的基元。有关更多信息,请参阅解析器映射模板概述。
之前映射模板
管道解析器的请求映射模板或预备步骤允许您在执行定义的函数之前执行一些准备逻辑。
函数列表
管道解析器将按顺序运行的函数的列表。管道解析器请求映射模板评估的结果可供第一个函数用作 $ctx.prev.result
。每个函数输出可供下一个函数用作 $ctx.prev.result
。
之后映射模板
管道解析器的响应映射模板或后续步骤允许您执行从最后一个函数的输出到预期 GraphQL 字段类型的一些最终映射逻辑。函数列表中最后一个函数的输出可在管道解析器映射模板中用作 $ctx.prev.result
或 $ctx.result
。
执行流程
假定一个管道解析器由两个函数组成,下面的列表表示调用解析器时的执行流程:
-
管道解析器的之前映射模板
-
函数 1:函数请求映射模板
-
函数 1:数据来源调用
-
函数 1:函数响应映射模板
-
函数 2:函数请求映射模板
-
函数 2:数据来源调用
-
函数 2:函数响应映射模板
-
管道解析器的之后映射模板
注意
管道解析器执行流是单向的,并在解析器上静态定义。
有用的 Apache Velocity 模板语言 (VTL) 实用工具
随着应用程序复杂性的增加,VTL实用程序和指令可以提高开发效率。在使用管道解析程序时,以下实用工具可为您提供帮助。
$ctx.stash
存储区是一个在每个解析器和函数映射模板中提供的Map
。同一存储实例通过单个解析程序生效。这意味着,您可以使用存储区来跨请求和响应映射模板以及管道解析器中的函数传递任意数据。存储区公开与 Java 映射
$ctx.prev.result
$ctx.prev.result
表示在管道解析器中执行的上一个操作的结果。
如果上一个操作是管道解析器的之前映射模板,则 $ctx.prev.result
表示模板评估的输出,并提供给管道中的第一个函数。如果上一个操作是第一个函数,则 $ctx.prev.result
表示第一个函数的输出,并且可供管道中的第二个函数使用。如果上一个操作是最后一个函数,则 $ctx.prev.result
表示最后一个函数的输出,并提供给管道解析器的之后映射模板。
#return(data: Object)
如果您需要从任何映射模板提前返回,#return(data: Object)
指令会很有用。#return(data: Object)
类似于编程语言中的 return 关键字,因为它会从最近的逻辑范围块返回。这意味着在解析器映射模板中使用 #return
会从解析器返回。在解析器映射模板中使用 #return(data: Object)
会在 GraphQL 字段上设置 data
。此外,从函数映射模板使用 #return(data: Object)
会从函数返回,并继续执行到管道中的下一个函数或解析器响应映射模板。
#return
这与 #return(data: Object)
相同,但返回 null
。
$util.error
$util.error
实用工具对于引发字段错误很有用。在函数映射模板中使用 $util.error
会立即引发字段错误,从而阻止执行后续函数。有关更多详细信息和其他 $util.error
签名,请访问解析器映射模板实用程序参考。
$util。 appendError
$util.appendError
类似于 $util.error()
,主要区别在于前者不会中断映射模板的评估。相反,它指示该字段存在错误,但允许评估模板并因此会返回数据。在函数中使用 $util.appendError
将不会中断管道的执行流。有关更多详细信息和其他 $util.error
签名,请访问解析器映射模板实用程序参考。
示例 模板
假设您在名为 getPost(id:ID!)
的字段上具有 DynamoDB 数据来源和单位解析器,该解析器使用以下 GraphQL 查询返回 Post
类型:
getPost(id:1){ id title content }
解析器模板应如下所示:
{ "version" : "2018-05-29", "operation" : "GetItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id) } }
这将替换 for 1
的id
输入参数值${ctx.args.id}
并生成以下内容JSON:
{ "version" : "2018-05-29", "operation" : "GetItem", "key" : { "id" : { "S" : "1" } } }
Amazon AppSync 使用此模板生成有关与 DynamoDB 通信和获取数据(或根据需要执行其他操作)的指令。数据返回后,通过可选的响应映射模板对其进行 Amazon AppSync 运行,您可以使用该模板来执行数据整形或逻辑。例如,在我们从 DynamoDB 中获取结果时,它们可能如下所示:
{ "id" : 1, "theTitle" : "Amazon AppSync works offline!", "theContent-part1" : "It also has realtime functionality", "theContent-part2" : "using GraphQL" }
您可以选择使用以下响应映射模板将两个字段联接成单一字段:
{ "id" : $util.toJson($context.data.id), "title" : $util.toJson($context.data.theTitle), "content" : $util.toJson("${context.data.theContent-part1} ${context.data.theContent-part2}") }
以下是将模板应用到数据后对设置数据形状的方式:
{ "id" : 1, "title" : "Amazon AppSync works offline!", "content" : "It also has realtime functionality using GraphQL" }
此数据作为响应返回给客户端,如下所示:
{ "data": { "getPost": { "id" : 1, "title" : "Amazon AppSync works offline!", "content" : "It also has realtime functionality using GraphQL" } } }
请注意,在大多数情况下,响应映射模板是简单的数据传递,主要由于您返回的是单个项目还是项目列表而不同。对于单个项目,传递:
$util.toJson($context.result)
对于列表,通常传递的是:
$util.toJson($context.result.items)
要查看单位解析器和管道解析器的更多示例,请参阅解析器教程。
评估的映射模板反序列化规则
映射模板评估结果为字符串。在中 Amazon AppSync,输出字符串必须遵循JSON结构才有效。
此外,将强制执行以下反序列化规则。
不允许在JSON对象中使用重复的密钥
如果评估后的映射模板字符串表示一个JSON对象或包含具有重复键的对象,则映射模板将返回以下错误消息:
Duplicate field 'aField' detected on Object. Duplicate JSON keys are not
allowed.
已评估的请求映射模板中的重复键示例:
{ "version": "2018-05-29", "operation": "Invoke", "payload": { "field": "getPost", "postId": "1", "field": "getPost" ## key 'field' has been redefined } }
要修复此错误,请勿在JSON对象中重新定义键。
对象中不允许使用尾随字符 JSON
如果评估后的映射模板字符串代表一个JSON对象并且包含尾随的多余字符,则映射模板将返回以下错误消息:
Trailing characters at the end of the JSON string are not allowed.
已评估的请求映射模板中的尾随字符示例:
{ "version": "2018-05-29", "operation": "Invoke", "payload": { "field": "getPost", "postId": "1", } }extraneouschars
要修复此错误,请确保经过评估的模板严格评估为JSON。