使用中的过滤器取消订阅 WebSocket 连接 AWS AppSync - AWS AppSync GraphQL

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

使用中的过滤器取消订阅 WebSocket 连接 AWS AppSync

在中 AWS AppSync,您可以根据特定的筛选逻辑强制取消订阅并关闭(使 WebSocket连接失效)来自已连接客户端的连接。这在与授权相关的场景中非常有用,例如,在您从组中删除用户时。

订阅失效是针对变更中定义的负载做出的响应。我们建议您将用于使订阅连接失效的变更视为 API 中的管理操作,并仅限管理员用户、组或后端服务使用这些变更以相应地设置其权限范围。例如,使用架构授权指令,例如 @aws_auth(cognito_groups: ["Administrators"])@aws_iam。有关更多信息,请参阅使用其他授权模式

失效筛选条件使用与增强订阅筛选条件相同的语法和逻辑。请使用以下实用程序定义这些筛选条件:

  • extensions.invalidateSubscriptions() - 在变更的 GraphQL 解析器响应处理程序中定义。

  • extensions.setSubscriptionInvalidationFilter() - 在链接到变更的订阅的 GraphQL 解析器响应处理程序中定义。

有关失效筛选扩展插件的更多信息,请参阅JavaScript 解析器概述。

使用订阅失效

要查看订阅失效的工作原理 AWS AppSync,请使用以下 GraphQL 架构:

type User { userId: ID! groupId: ID! } type Group { groupId: ID! name: String! members: [ID!]! } type GroupMessage { userId: ID! groupId: ID! message: String! } type Mutation { createGroupMessage(userId: ID!, groupId : ID!, message: String!): GroupMessage removeUserFromGroup(userId: ID!, groupId : ID!) : User @aws_iam } type Subscription { onGroupMessageCreated(userId: ID!, groupId : ID!): GroupMessage @aws_subscribe(mutations: ["createGroupMessage"]) } type Query { none: String }

removeUserFromGroup 变更解析器代码中定义失效筛选条件:

import { extensions } from '@aws-appsync/utils'; export function request(ctx) { return { payload: null }; } export function response(ctx) { const { userId, groupId } = ctx.args; extensions.invalidateSubscriptions({ subscriptionField: 'onGroupMessageCreated', payload: { userId, groupId }, }); return { userId, groupId }; }

在调用变更时,payload 对象中定义的数据用于取消订阅 subscriptionField 中定义的订阅。还会在 onGroupMessageCreated 订阅的响应映射模板中定义一个失效筛选条件。

如果extensions.invalidateSubscriptions()有效负载包含与过滤器中定义的 IDs来自已订阅客户端的 ID 相匹配,则相应的订阅将被取消订阅。此外, WebSocket 连接已关闭。定义 onGroupMessageCreated 订阅的订阅解析器代码:

import { util, extensions } from '@aws-appsync/utils'; export function request(ctx) { // simplfy return null for the payload return { payload: null }; } export function response(ctx) { const filter = { groupId: { eq: ctx.args.groupId } }; extensions.setSubscriptionFilter(util.transform.toSubscriptionFilter(filter)); const invalidation = { groupId: { eq: ctx.args.groupId }, userId: { eq: ctx.args.userId } }; extensions.setSubscriptionInvalidationFilter(util.transform.toSubscriptionFilter(invalidation)); return null; }

请注意,订阅响应处理程序可以同时定义订阅筛选条件和失效筛选条件。

例如,假设客户端 A 使用以下订阅请求为具有 ID user-1 的新用户订阅具有 ID group-1 的组:

onGroupMessageCreated(userId : "user-1", groupId: :"group-1"){...}

AWS AppSync 运行订阅解析器,该解析器生成前面的onGroupMessageCreated响应映射模板中定义的订阅和失效过滤器。对于客户端 A,订阅筛选条件仅允许将数据发送到 group-1,并为 user-1group-1 定义了失效筛选条件。

现在假设客户端 B 使用以下订阅请求为具有 ID user-2 的用户订阅具有 ID group-2 的组:

onGroupMessageCreated(userId : "user-2", groupId: :"group-2"){...}

AWS AppSync 运行订阅解析器,它会生成订阅和失效过滤器。对于客户端 B,订阅筛选条件仅允许将数据发送到 group-2,并为 user-2group-2 定义了失效筛选条件。

接下来,假设使用变更请求创建 ID 为 message-1 的新组消息,如以下示例中所示:

createGroupMessage(id: "message-1", groupId : "group-1", message: "test message"){...}

与定义的过滤器匹配的订阅客户端会自动通过 WebSockets以下方式接收以下数据有效负载:

{ "data": { "onGroupMessageCreated": { "id": "message-1", "groupId": "group-1", "message": "test message", } } }

客户端 A 收到该消息,因为筛选条件与定义的订阅筛选条件匹配。不过,客户端 B 不会收到该消息,因为该用户不属于 group-1。此外,请求与订阅解析器中定义的订阅筛选条件不匹配。

最后,假设使用以下变更请求从 group-1 中删除了 user-1

removeUserFromGroup(userId: "user-1", groupId : "group-1"){...}

该突变会启动订阅失效,如其extensions.invalidateSubscriptions()解析器响应处理程序代码中所定义。 AWS AppSync 然后取消订阅客户端 A 并关闭其连接。 WebSocket 客户端 B 不受影响,因为变更中定义的失效负载与其用户或组不匹配。

当连接 AWS AppSync 失效时,客户端会收到一条消息,确认他们已取消订阅:

{ "message": "Subscription complete." }

在订阅失效筛选条件中使用上下文变量

与增强订阅筛选条件一样,您可以在订阅失效筛选条件扩展中使用 context 变量以访问某些数据。

例如,可以在变更中将电子邮件地址配置为失效负载,然后将其与通过 Amazon Cognito 用户池或 OpenID Connect 授权的订阅用户的电子邮件属性或声明进行匹配。失效筛选条件(在 extensions.setSubscriptionInvalidationFilter() 订阅失效器中定义)检查变更的 extensions.invalidateSubscriptions() 负载设置的电子邮件地址是否与从用户 JWT 令牌的 context.identity.claims.email 中检索的电子邮件地址匹配,从而启动失效。