本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
Lambda 的解析程序映射模板参考
您可以使用AmazonAppSync 解析器映射模板Amazon Lambda调整来自的请求Amazon对于位于您账户中的 Lambda 函数的 AppSync 函数以及从 Lambda 函数返回到的响应AmazonAppSync。您还可以使用映射模板向提供提示:AmazonAppSync 介绍要调用的操作的性质。本节介绍用于支持的 Lambda 操作的不同映射模板。
请求映射模板
Lambda 请求映射模板相当简单,允许尽可能多的上下文信息传递到 Lambda 函数。
{ "version": string, "operation": Invoke|BatchInvoke, "payload": any type }
下面是 Lambda 请求映射模板的 JSON 架构表示形式(解析后)。
{ "definitions": {}, "$schema": "https://json-schema.org/draft-06/schema#", "$id": "https://aws.amazon.com/appsync/request-mapping-template.json", "type": "object", "properties": { "version": { "$id": "/properties/version", "type": "string", "enum": [ "2018-05-29" ], "title": "The Mapping template version.", "default": "2018-05-29" }, "operation": { "$id": "/properties/operation", "type": "string", "enum": [ "Invoke", "BatchInvoke" ], "title": "The Mapping template operation.", "description": "What operation to execute.", "default": "Invoke" }, "payload": {} }, "required": [ "version", "operation" ], "additionalProperties": false }
下面是我们通过的示例:field
值以及上下文中的 GraphQL 字段参数。
{ "version": "2018-05-29", "operation": "Invoke", "payload": { "field": "getPost", "arguments": $util.toJson($context.arguments) } }
将整个映射文档作为输入传递到 Lambda 函数,因此,前面的示例将如下所示:
{ "version": "2018-05-29", "operation": "Invoke", "payload": { "field": "getPost", "arguments": { "id": "postId1" } } }
版本
version
定义模板使用的版本,这一点对于所有请求映射模板都相同。version
是必需的。
"version": "2018-05-29"
运算
Lambda 数据源允许您定义两种操作:Invoke
和BatchInvoke
. 这些区域有:Invoke
操作允许AmazonAppSync 知道为每个 GraphQL 字段解析程序调用 Lambda 函数。BatchInvoke
指示AmazonAppSync 用于批量对当前 GraphQL 字段的请求。
operation
是必需的。
适用于Invoke
,已解析的请求映射模板与 Lambda 函数的输入负载完全匹配。因此,下面的示例模板:
{ "version": "2018-05-29", "operation": "Invoke", "payload": { "arguments": $util.toJson($context.arguments) } }
经过解析并传递给 Lambda 函数,如下所示:
{ "version": "2018-05-29", "operation": "Invoke", "payload": { "arguments": { "id": "postId1" } } }
适用于BatchInvoke
,映射模板将应用于批处理中的每个字段解析程序。为了简洁起见,AmazonAppSync 合并所有已解析的映射模板payload
在与映射模板匹配的单一对象下的列表中。
以下示例模板显示合并:
{ "version": "2018-05-29", "operation": "BatchInvoke", "payload": $util.toJson($context) }
此模板解析为以下映射文档:
{ "version": "2018-05-29", "operation": "BatchInvoke", "payload": [ {...}, // context for batch item 1 {...}, // context for batch item 2 {...} // context for batch item 3 ] }
其中,payload
列表的每个元素对应于一个批处理项目。Lambda 函数也预期返回列表形状的响应,并与请求中发送的项目顺序匹配,如下所示:
[ { "data": {...}, "errorMessage": null, "errorType": null }, // result for batch item 1 { "data": {...}, "errorMessage": null, "errorType": null }, // result for batch item 2 { "data": {...}, "errorMessage": null, "errorType": null } // result for batch item 3 ]
operation
是必需的。
有效负载
payload
字段是一个容器,可用于将任何格式正确的 JSON 传递到 Lambda 函数。
如果operation
字段设置为BatchInvoke
、AmazonAppSync 包装了现有的payload
值转入列表中。
payload
为可选项。
响应映射模板
与其他数据源一样,Lambda 函数将响应发送到Amazon必须转换为 GraphQL 类型的 AppSync。
Lambda 函数的结果设置在context
通过 Velocity 模板语言 (VTL) 提供的对象(VTL)$context.result
财产。
如果 Lambda 函数响应的形状与 GraphQL 类型的形状完全匹配,您可以使用以下响应映射模板转发响应:
$util.toJson($context.result)
没有必填字段,也没有形状限制应用于响应映射模板。但是,由于 GraphQL 是强类型化的,因此解析的映射模板必须与预期的 GraphQL 类型匹配。
响应 Lambda 函数批处理
如果operation
字段设置为BatchInvoke
、AmazonAppSync 预计从 Lambda 函数返回项目列表。为了AmazonAppSync 要将每个结果映射回原始请求项目,响应列表在大小和顺序方面必须匹配。没关系null
响应列表中的项目;$ctx.result
设置为null相应地。
直接 Lambda 解析程序
如果你想完全规避使用映射模板,AmazonAppSync 可以为您的 Lambda 函数提供默认负载以及 Lambda 函数对 GraphQL 类型的默认响应。您可以选择提供请求模板、响应模板或两者都不提供,以及AmazonAppSync 会相应地处理它。
直接 Lambda 请求映射模板
如果未提供请求映射模板,AmazonAppSync 将发送Context
直接将对象作为 Lambda 函数Invoke
operation. 有关 Context
对象结构的更多信息,请参阅 解析器映射模板上下文参考。
直接 Lambda 响应映射模板
如果没有提供响应映射模板,AmazonAppSync 在收到 Lambda 函数响应后执行以下两件事之一。如果您没有提供请求映射模板,或者如果您提供了版本为 “2018-05-29” 的请求映射模板,则响应逻辑功能与以下响应映射模板相当:
#if($ctx.error) $util.error($ctx.error.message, $ctx.error.type, $ctx.result) #end $util.toJson($ctx.result)
如果您提供了版本为 “2017-02-28” 的模板,则响应逻辑的功能与以下响应映射模板相同:
$util.toJson($ctx.result)
表面上,映射模板绕过的操作方式与使用某些映射模板类似,如前面的示例所示。但是,在幕后,完全绕过了对映射模板的评估。由于模板评估步骤被绕过,因此与需要评估的响应映射模板的 Lambda 函数相比,在某些情况下,应用程序在响应期间可能会遇到的开销和延迟较少。
直接 Lambda 解决器响应中的自定义错误处理
您可以通过引发自定义异常,从直接 Lambda 解析器调用的 Lambda 函数自定义错误响应。以下示例演示如何使用 JavaScript 创建自定义异常:
class CustomException extends Error { constructor(message) { super(message); this.name = "CustomException"; } } throw new CustomException("Custom message");
当出现例外情况时,errorType
和errorMessage
是name
和message
,分别是引发的自定义错误的信息。
如果errorType
是UnauthorizedException
、AmazonAppSync 返回默认消息("You are not authorized to make this
call."
) 而不是自定义消息。
以下是 GraphQL 响应示例,演示自定义:errorType
.
{ "data": { "query": null }, "errors": [ { "path": [ "query" ], "data": null, "errorType": "CustomException", "errorInfo": null, "locations": [ { "line": 5, "column": 10, "sourceName": null } ], "message": "Custom Message" } ] }
直接 Lambda 解析程序:启用批处理
您可以通过配置为直接 Lambda 解析器启用批处理maxBatchSize
在解析程序上。何时maxBatchSize
对于直接 Lambda 解析程序,设置为大于 0 的值,AmazonAppSync 将请求批量发送到您的 Lambda 函数,其大小不超过maxBatchSize
.
设置maxBatchSize
直接 Lambda 解析器上的设置为 0 关闭批处理。
有关使用 Lambda 解析程序批处理的更多信息,请参阅:高级用例:批处理.
请求映射模板
启用批处理且未提供请求映射模板时,AmazonAppSync 发送了一份列表Context
对象作为BatchInvoke
直接对 Lambda 函数进行操作。
响应映射模板
启用批处理且未提供响应映射模板时,响应逻辑等同于以下响应映射模板:
#if( $context.result && $context.result.errorMessage ) $utils.error($context.result.errorMessage, $context.result.errorType, $context.result.data) #else $utils.toJson($context.result.data) #end
Lambda 函数必须按照与列表相同的顺序返回结果列表Context
已发送的对象。您可以通过提供一个errorMessage
和errorType
获取具体结果。列表中的每个结果都遵循以下格式:
{ "data" : { ... }, // your data "errorMessage" : { ... }, // optional, if included an error entry is added to the "errors" object in the AppSync response "errorType" : { ... } // optional, the error type }
结果对象中的其他字段当前被忽略。
处理 Lambda 的错误
您可以通过在 Lambda 函数中抛出异常或错误来返回所有结果的错误。如果批处理请求的有效负载请求或响应大小太大,Lambda 会返回错误。在这种情况下,您应当考虑减少您的maxBatchSize
或减小响应负载的大小。
有关处理单个错误的信息,请参阅返回单个错误.
示例 Lambda 函数
使用下面的模式,Lambda 可以为Post.relatedPosts
字段解析器并通过设置启用批处理maxBatchSize
大于 0:
schema { query: Query mutation: Mutation } type Query { getPost(id:ID!): Post allPosts: [Post] } type Mutation { addPost(id: ID!, author: String!, title: String, content: String, url: String): Post! } type Post { id: ID! author: String! title: String content: String url: String ups: Int downs: Int relatedPosts: [Post] }
在以下查询中,将通过批次请求调用 Lambda 函数以解决relatedPosts
:
query getAllPosts { allPosts { id relatedPosts { id } } }
下面提供了 Lambda 函数的简单实现:
const posts = { 1: { id: '1', title: 'First book', author: 'Author1', url: 'https://amazon.com/', content: 'SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1', ups: '100', downs: '10', }, 2: { id: '2', title: 'Second book', author: 'Author2', url: 'https://amazon.com', content: 'SAMPLE TEXT AUTHOR 2 SAMPLE TEXT AUTHOR 2 SAMPLE TEXT', ups: '100', downs: '10', }, 3: { id: '3', title: 'Third book', author: 'Author3', url: null, content: null, ups: null, downs: null }, 4: { id: '4', title: 'Fourth book', author: 'Author4', url: 'https://www.amazon.com/', content: 'SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4', ups: '1000', downs: '0', }, 5: { id: '5', title: 'Fifth book', author: 'Author5', url: 'https://www.amazon.com/', content: 'SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT', ups: '50', downs: '0', }, } const relatedPosts = { 1: [posts['4']], 2: [posts['3'], posts['5']], 3: [posts['2'], posts['1']], 4: [posts['2'], posts['1']], 5: [], } exports.handler = async (event) => { console.log('event ->', event) // retrieve the ID of each post const ids = event.map((context) => context.source.id) // fetch the related posts for each post id const related = ids.map((id) => relatedPosts[id]) // return the related posts; or an error if none were found return related.map((r) => { if (r.length > 0) { return { data: r } } else { return { data: null, errorMessage: 'Not found', errorType: 'ERROR' } } }) }