解析程序映射模板上下文参考 - Amazon AppSync
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

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

解析程序映射模板上下文参考

Amazon AppSync定义了一组变量和函数,以便使用解析程序映射模板。这样,就可以更轻松地通过 GraphQL 对数据进行逻辑操作。本文档将介绍这些函数,并提供使用模板的示例。

使用 $context

$context 变量是一个映射,它保留进行解析程序调用的所有上下文信息。它具有以下结构:

{ "arguments" : { ... }, "source" : { ... }, "result" : { ... }, "identity" : { ... }, "request" : { ... }, "info": { ... } }

注意:如果您试图访问字典/地图条目(例如中的条目context) 通过检索其值的键,Velocity 模板语言 (VTL) 允许您直接使用表示法。<dictionary-element>.<key-name>. 但是,这可能不适用于所有情况,例如当键名称具有特殊字符时(例如,下划线“_”)。建议您始终使用 <dictionary-element>.get("<key-name>") 表示法。

$context 映射中每个字段的定义如下所示:

arguments

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

identity

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

source

包含父字段解析的映射。

stash

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

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表示第一个函数的输出,并且可供管道中的第二个函数使用。如果之前的操作是最后一个函数,那么$ctx.prev.result表示最后一个函数的输出,并且可供管道解析程序响应映射模板使用。

info

包含有关 GraphQL 请求的信息的对象。有关此字段的结构,请参阅信息

求同

identity 部分包含调用方的相关信息。此部分的形态取决于您的 Amazon AppSync API 的授权类型。

有关 的更多信息AmazonAppSync 安全选项,请参阅授权和身份验证.

API_KEY 授权

这些区域有:identity字段未填充。

AWS_LAMBDA 授权

这些区域有:identity包含resolverContextkey,包含相同的resolverContext由授权请求的 Lambda 函数返回的内容。

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

这些区域有:Amazon调用者的账户 ID。

claims

用户拥有的声明。

cognitoIdentityAuthType

根据身份类型确定经过身份验证或未经身份验证。

cognitoIdentityAuthProvider

外部身份提供商信息的逗号分隔列表,以便获取用于为请求签名的凭证。

cognitoIdentityId

调用者的 Amazon Cognito 身份 ID。

cognitoIdentityPoolId

与调用者关联的 Amazon Cognito 身份池 ID。

defaultAuthStrategy

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

issuer

令牌发布者。

sourceIp

调用者的源 IP 地址Amazon AppSync接收。如果请求中不包括x-forwarded-for标头,源 IP 值仅包含来自 TCP 连接的单一 IP 地址。如果请求中包含 x-forwarded-for 标头,那么源 IP 将是来自 x-forwarded-for 标头的 IP 地址列表,以及来自 TCP 连接的 IP 地址。

sub

经过验证的用户的 UUID。

user

IAM 用户。

userArn

IAM 用户的 Amazon 资源名称 (ARN)。

username

已验证的用户的用户名。对于 AMAZON_COGNITO_USER_POOLS 授权,用户名的值是 cognito:username 属性的值。如果是AWS_IAM授权,值用户名是的价值Amazon用户主体。如果您使用的 IAM 授权由 Amazon Cognito 身份池提供凭证,我们建议您使用cognitoIdentityId.

访问请求标头

Amazon通过使用 AppSync 支持从客户端传递自定义标头,还支持使用在您的 GraphQL 解析$context.request.headers. 然后,您可以将标头值用于操作,例如将数据插入数据源或授权检查。你可以使用单个或多个请求标头$curl从命令行中使用 API 密钥,如以下示例所示:

单一标头示例

假设您设置一个 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]"

注意: Amazon AppSync没有在中公开 cookie 标题$context.request.headers.

访问请求自定义域名

Amazon AppSync支持配置可用于访问 GraphQL 和实时访问的自定义域终端为您的 API。使用自定义域名进行请求时,您可以使用$context.request.domainName.

使用默认 GraphQL 终端节点域名时,值为null.

Info

info 部分包含有关 GraphQL 请求的信息。此部分具有以下形态:

{ "fieldName": "string", "parentTypeName": "string", "variables": { ... }, "selectionSetList": ["string"], "selectionSetGraphQL": "string" }

每个字段的定义如下所示:

fieldName

当前正在解析的字段的名称。

parentTypeName

当前正在解析的字段的父类型的名称。

variables

保留传递到 GraphQL 请求的所有变量的映射。

selectionSetList

GraphQL 选择集中字段的列表表示形式。具有别名的字段仅由别名(而不是字段名称)引用。以下示例对此详细进行了介绍。

selectionSetGraphQL

选择集的字符串表示形式,格式为 GraphQL 架构定义语言 (SDL)。尽管片段不会合并到选择集中,但内联片段会保留下来,如以下示例所示。

注意:使用$utils.toJson()context.info,那些价值观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 } } }

打电话时$ctx.info.selectionSetListQuery.node仅限现场分辨率id被曝光:

"selectionSetList": [ "id" ]

清理输入

应用程序必须对不可信的输入进行清理,以防止任何外部方在应用程序的预期用途之外使用该应用程序。作为$context包含属性中的用户输入,例如$context.arguments$context.identity$context.result$context.info.variables, 和$context.request.headers, 必须注意在映射模板中清理其价值.

由于映射模板代表 JSON,因此输入清理采用从表示用户输入的字符串转义 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. } }