本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
AWS AppSync 解析器映射模板上下文参考
注意
我们现在主要支持 APPSYNC _JS 运行时及其文档。请考虑在此处使用 APPSYNC _JS 运行时及其指南。
AWS AppSync 定义了一组用于处理解析器映射模板的变量和函数。这样,就可以更轻松地通过 GraphQL 对数据进行逻辑操作。本文档将介绍这些函数,并提供使用模板的示例。
使用 $context
$context
变量是一个映射,它保留进行解析器调用的所有上下文信息。它具有以下结构:
{ "arguments" : { ... }, "source" : { ... }, "result" : { ... }, "identity" : { ... }, "request" : { ... }, "info": { ... } }
注意
如果您尝试通过键访问字典/地图条目(例如中的条目context
)来检索该值,Velocity 模板语言 (VTL) 允许您直接使用该符号。<dictionary-element>.<key-name>
但是,这可能不适用于所有情况,例如当键名称具有特殊字符时(例如,下划线“_”)。建议您始终使用 <dictionary-element>.get("<key-name>")
表示法。
$context
映射中每个字段的定义如下所示:
$context
字段
-
result
-
此解析器结果的容器。该字段仅适用于响应映射模板。
例如,如果要解析以下查询的
author
字段:query { getPost(id: 1234) { postId title content author { id name } } }
那么在处理响应映射模板时,完整的
$context
变量可以是:{ "arguments" : { id: "1234" }, "source": {}, "result" : { "postId": "1234", "title": "Some title", "content": "Some content", "author": { "id": "5678", "name": "Author Name" } }, "identity" : { "sourceIp" : ["x.x.x.x"], "userArn" : "arn:aws:iam::123456789012:user/appsync", "accountId" : "666666666666", "user" : "AIDAAAAAAAAAAAAAAAAAA" } }
-
prev.result
-
在管道解析器中执行的任何以前操作的结果。
如果上一个操作是管道解析器的之前映射模板,则
$ctx.prev.result
表示模板评估的输出,并提供给管道中的第一个函数。如果上一个操作是第一个函数,则
$ctx.prev.result
表示第一个函数的输出,并且可供管道中的第二个函数使用。如果上一个操作是最后一个函数,则
$ctx.prev.result
表示最后一个函数的输出,并提供给管道解析器的之后映射模板。 -
info
-
包含有关 GraphQL 请求的信息的对象。有关该字段的结构,请参阅信息。
求同
identity
部分包含调用方的相关信息。此部分的形式取决于您的授权类型 AWS AppSync API。
有关 AWS AppSync 安全选项的更多信息,请参阅授权和身份验证。
-
API_KEY
授权 -
不填充
identity
字段。 AWS_LAMBDA
授权-
identity
包含resolverContext
密钥,其中包含为请求授权的 Lambda 函数返回的相同resolverContext
内容。 -
AWS_IAM
授权 -
identity
采用以下格式:{ "accountId" : "string", "cognitoIdentityPoolId" : "string", "cognitoIdentityId" : "string", "sourceIp" : ["string"], "username" : "string", // IAM user principal "userArn" : "string", "cognitoIdentityAuthType" : "string", // authenticated/unauthenticated based on the identity type "cognitoIdentityAuthProvider" : "string" // the auth provider that was used to obtain the credentials }
-
AMAZON_COGNITO_USER_POOLS
授权 -
identity
采用以下格式:{ "sub" : "uuid", "issuer" : "string", "username" : "string" "claims" : { ... }, "sourceIp" : ["x.x.x.x"], "defaultAuthStrategy" : "string" }
每个字段的定义如下所示:
-
accountId
-
来电者的 AWS 账户 ID。
-
claims
-
用户拥有的声明。
-
cognitoIdentityAuthType
-
根据身份类型确定经过身份验证或未经身份验证。
-
cognitoIdentityAuthProvider
-
外部身份提供程序信息的逗号分隔列表,用于获取对请求进行签名时使用的凭证。
-
cognitoIdentityId
-
调用方的 Amazon Cognito 身份 ID。
-
cognitoIdentityPoolId
-
与调用方关联的 Amazon Cognito 身份池 ID。
-
defaultAuthStrategy
-
此调用方的默认授权策略(
ALLOW
或DENY
)。 -
issuer
-
令牌发布者。
-
sourceIp
-
AWS AppSync 接收的来电者的源 IP 地址。如果请求不包含
x-forwarded-for
标头,则源 IP 值仅包含来自TCP连接的单个 IP 地址。如果请求包含x-forwarded-for
标头,则源 IP 除了来自TCP连接的 IP 地址外,还包括x-forwarded-for
标头中的 IP 地址列表。 -
sub
-
经过身份验证UUID的用户的。
-
user
-
IAM用户。
-
userArn
-
IAM用户的亚马逊资源名称 (ARN)。
-
username
-
已验证的用户的用户名。对于
AMAZON_COGNITO_USER_POOLS
授权,用户名的值是 cognito:username 属性的值。在AWS_IAM
授权的情况下,用户名的值就是 AWS 用户委托人的值。如果您使用的是通过 Amazon Cognito 身份池出售的凭证进行IAM授权,我们建议您使用。cognitoIdentityId
访问请求标头
AWS AppSync 支持从客户端传递自定义标头并使用在 GraphQL 解析器中访问它们。$context.request.headers
然后,您可以使用标头值执行操作,例如,将数据插入到数据来源或进行授权检查。您可以通过命令行中的API密钥$curl
使用单个或多个请求标头,如以下示例所示:
单标头示例
假设您设置一个 custom
标头,值为 nadia
,如下所示:
curl -XPOST -H "Content-Type:application/graphql" -H "custom:nadia" -H "x-api-key:<API-KEY-VALUE>" -d '{"query":"mutation { createEvent(name: \"demo\", when: \"Next Friday!\", where: \"Here!\") {id name when where description}}"}' https://<ENDPOINT>/graphql
然后可使用 $context.request.headers.custom
访问它。例如,对于 DynamoDB,它可能出现在以下内容VTL中:
"custom": $util.dynamodb.toDynamoDBJson($context.request.headers.custom)
多标头示例
您还可以在一个请求中传递多个标头,并在解析器映射模板中访问它们。例如,如果为 custom
标头设置了两个值:
curl -XPOST -H "Content-Type:application/graphql" -H "custom:bailey" -H "custom:nadia" -H "x-api-key:<API-KEY-VALUE>" -d '{"query":"mutation { createEvent(name: \"demo\", when: \"Next Friday!\", where: \"Here!\") {id name when where description}}"}' https://<ENDPOINT>/graphql
它们可以作为一个数组访问,例如 $context.request.headers.custom[1]
。
注意
AWS AppSync 不会在中公开 cookie 标头$context.request.headers
。
访问请求自定义域名
AWS AppSync 支持配置自定义域,您可以使用该域名访问您的 GraphQL 和实时终端节点。APIs在使用自定义域名发出请求时,您可以使用 $context.request.domainName
获取域名。
在使用默认 GraphQL 终端节点域名时,值为 null
。
信息
info
部分包含有关 GraphQL 请求的信息。该部分采用以下格式:
{ "fieldName": "string", "parentTypeName": "string", "variables": { ... }, "selectionSetList": ["string"], "selectionSetGraphQL": "string" }
每个字段的定义如下所示:
-
fieldName
-
当前正在解析的字段的名称。
-
parentTypeName
-
当前正在解析的字段的父类型的名称。
-
variables
-
保留传递到 GraphQL 请求的所有变量的映射。
-
selectionSetList
-
GraphQL 选择集中字段的列表表示形式。具有别名的字段仅按别名进行引用,而不按字段名称进行引用。以下示例对此详细进行了介绍。
-
selectionSetGraphQL
-
选择集的字符串表示形式,格式为 GraphQL 架构定义语言 () SDL。尽管片段不会合并到选择集中,但会保留内联片段,如以下示例中所示。
注意
默认情况下,在 context.info
上使用 $utils.toJson()
时,不会序列化 selectionSetGraphQL
和 selectionSetList
返回的值。
例如,如果您要解析以下查询的 getPost
字段:
query { getPost(id: $postId) { postId title secondTitle: title content author(id: $authorId) { authorId name } secondAuthor(id: "789") { authorId } ... on Post { inlineFrag: comments: { id } } ... postFrag } } fragment postFrag on Post { postFrag: comments: { id } }
那么,在处理映射模板时可用的完整 $context.info
变量可以是:
{ "fieldName": "getPost", "parentTypeName": "Query", "variables": { "postId": "123", "authorId": "456" }, "selectionSetList": [ "postId", "title", "secondTitle" "content", "author", "author/authorId", "author/name", "secondAuthor", "secondAuthor/authorId", "inlineFragComments", "inlineFragComments/id", "postFragComments", "postFragComments/id" ], "selectionSetGraphQL": "{\n getPost(id: $postId) {\n postId\n title\n secondTitle: title\n content\n author(id: $authorId) {\n authorId\n name\n }\n secondAuthor(id: \"789\") {\n authorId\n }\n ... on Post {\n inlineFrag: comments {\n id\n }\n }\n ... postFrag\n }\n}" }
selectionSetList
仅公开属于当前类型的字段。如果当前类型是接口或联合,则仅公开属于该接口的选定字段。例如,给定以下架构:
type Query { node(id: ID!): Node } interface Node { id: ID } type Post implements Node { id: ID title: String author: String } type Blog implements Node { id: ID title: String category: String }
以及以下查询:
query { node(id: "post1") { id ... on Post { title } ... on Blog { title } } }
如果在进行 Query.node
字段解析时调用 $ctx.info.selectionSetList
,则仅公开 id
:
"selectionSetList": [ "id" ]
清理输入
应用程序必须对不可信的输入进行清理,以防止任何外部方在应用程序的预期用途之外使用该应用程序。由于 $context
包含 $context.arguments
、$context.identity
、$context.result
、$context.info.variables
和 $context.request.headers
等属性中的用户输入,因此,务必谨慎在映射模板中清理它们的值。
由于映射模板表示JSON,因此输入清理的形式是从代表用户输入的字符串中转义JSON保留字符。在将保留字符放入映射模板时,最佳做法是使用该$util.toJson()
实用程序将JSON保留字符从敏感字符串值中转义。
例如,在下面的 Lambda 请求映射模板中,由于我们访问了一个不安全的客户输入字符串 ($context.arguments.id
),因此我们将其封装起来,$util.toJson()
以防止未转义的JSON字符破坏模板。JSON
{ "version": "2017-02-28", "operation": "Invoke", "payload": { "field": "getPost", "postId": $util.toJson($context.arguments.id) } }
下面的映射模板与之相反,我们直接插入 $context.arguments.id
而不进行清理。这不适用于包含未转义引号或其他JSON保留字符的字符串,并且可能会使您的模板容易失败。
## DO NOT DO THIS { "version": "2017-02-28", "operation": "Invoke", "payload": { "field": "getPost", "postId": "$context.arguments.id" ## Unsafe! Do not insert $context string values without escaping JSON characters. } }