AWS AppSync 解析器映射模板上下文参考 - AWS AppSync

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

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 字段

arguments

包含该字段的所有 GraphQL 参数的映射。

identity

包含有关调用方的信息的对象。有关该字段结构的更多信息,请参阅身份

source

包含父字段解析的映射。

stash

存储区是一个在每个解析器和函数映射模板中提供的映射。同一存储实例通过单个解析程序生效。这意味着,您可以使用存储区来跨请求和响应映射模板以及管道解析器中的函数传递任意数据。存储区公开与 Java 映射数据结构相同的方法。

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

此调用方的默认授权策略(ALLOWDENY)。

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() 时,不会序列化 selectionSetGraphQLselectionSetList 返回的值。

例如,如果您要解析以下查询的 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. } }