解析器上下文对象引用 - Amazon AppSync
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

解析器上下文对象引用

Amazon AppSync 定义了一组用于处理请求和响应处理程序的变量和函数。这样,就可以更轻松地通过 GraphQL 对数据进行逻辑操作。本文档介绍了这些函数并提供了示例。

使用 context

请求和响应处理程序的 context 参数是一个对象,它保存解析器调用的所有上下文信息。它具有以下结构:

type Context = { arguments: any; args: any; identity: Identity; source: any; error?: { message: string; type: string; }; stash: any; result: any; prev: any; request: Request; info: Info; };
注意

您经常会发现 context 对象是作为 ctx 引用的。

context 对象中的每个字段定义如下:

context 字段

arguments

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

identity

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

source

包含父字段解析的映射。

stash

存储区是一个在每个解析器以及函数处理程序中提供的对象。相同的存储区对象在单次解析器运行时间内有效。这意味着,您可以使用存储区在请求和响应处理程序之间以及管道解析器中的函数之间传送任意数据。

注意

您无法删除或替换整个存储区,但可以添加、更新、删除和读取存储区属性。

您可以修改以下代码示例之一,以将项目添加到存储区中:

//Example 1 ctx.stash.newItem = { key: "something" } //Example 2 Object.assign(ctx.stash, {key1: value1, key2: value})

您可以修改以下代码,以从存储区中删除项目:

delete ctx.stash.key
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 部分包含调用方的相关信息。此部分的形态取决于您的 Amazon AppSync API 的授权类型。

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

API_KEY 授权

不填充 identity 字段。

AWS_LAMBDA 授权

identity 采用以下格式:

type AppSyncIdentityLambda = { resolverContext: any; };

identity 包含 resolverContext 密钥,其中包含为请求授权的 Lambda 函数返回的相同 resolverContext 内容。

AWS_IAM 授权

identity 采用以下格式:

type AppSyncIdentityIAM = { accountId: string; cognitoIdentityPoolId: string; cognitoIdentityId: string; sourceIp: string[]; username: string; userArn: string; cognitoIdentityAuthType: string; cognitoIdentityAuthProvider: string; };
AMAZON_COGNITO_USER_POOLS 授权

identity 采用以下格式:

type AppSyncIdentityCognito = { sourceIp: string[]; username: string; groups: string[] | null; sub: string; issuer: string; claims: any; defaultAuthStrategy: string; };

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

accountId

调用方的 Amazon 账户 ID。

claims

用户拥有的声明。

cognitoIdentityAuthType

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

cognitoIdentityAuthProvider

外部身份提供程序信息的逗号分隔列表,用于获取对请求进行签名时使用的凭证。

cognitoIdentityId

调用方的 Amazon Cognito 身份 ID。

cognitoIdentityPoolId

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

defaultAuthStrategy

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

issuer

令牌发布者。

sourceIp

Amazon AppSync 收到的调用方的源 IP 地址。如果请求不包含 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 授权,username 值是 Amazon 用户主体的值。如果您将 IAM 授权与从 Amazon Cognito 身份池提供的凭证一起使用,我们建议您使用 cognitoIdentityId

访问请求标头

Amazon AppSync 支持从客户端传递自定义标头,并使用 ctx.request.headers 在 GraphQL 解析器中访问这些标头。然后,您可以使用标头值执行操作,例如,将数据插入到数据源或进行授权检查。您可以在命令行中使用 $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

然后可使用 ctx.request.headers.custom 访问它。例如,对于 DynamoDB,它可能位于以下代码中:

"custom": util.dynamodb.toDynamoDB(ctx.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

它们可以作为一个数组访问,例如 ctx.request.headers.custom[1]

注意

Amazon AppSync 不会在 ctx.request.headers 中公开 Cookie 标头。

访问请求自定义域名

Amazon AppSync 支持配置自定义域,您可以使用该域访问 API 的 GraphQL 和实时终端节点。在使用自定义域名发出请求时,您可以使用 ctx.request.domainName 获取域名。

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

Info

info 部分包含有关 GraphQL 请求的信息。该部分采用以下格式:

type Info = { fieldName: string; parentTypeName: string; variables: any; selectionSetList: string[]; selectionSetGraphQL: string; };

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

fieldName

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

parentTypeName

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

variables

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

selectionSetList

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

selectionSetGraphQL

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

注意

JSON.stringify 不会在字符串序列化中包含 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 } }

在处理处理程序时可使用的完整 ctx.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" ]