亚马逊云科技 AppSync 基于 WebSockets 的实时更新订阅现在支持嵌套筛选

作者: Brice Pellé | 202 3 年 9 月

亚马逊云科技 AppSync 是一项完全托管的服务,使开发人员能够基于实时数据构建数字体验。使用 AppSync,您可以配置数据源以向订阅的客户端推送和发布实时数据更新。AppSync 处理连接管理、可扩展性、扇出和广播,使您能够专注于应用程序业务需求,而不必管理复杂的基础架构。借助 AppSync,开发人员可以根据已发布的数据轻松指定针对特定联网客户端的订阅的筛选规则。

今天,AppSync 引入了对 增强订阅过滤器中嵌套架构字段进行筛选 的支持。通过此更改,您现在可以定位突变选择集中发布的数据中的特定子项。这使您可以进一步控制应如何通过订阅广播数据。您可以在架构中创建由复杂字段组成的类型,也可以创建最多具有五个嵌套级别的订阅。您无需更改嵌套架构类型,可以立即开始使用 AppSync 发布/订阅引擎的此功能来实现实时体验。

入门

为了展示如何开始在自己的应用程序中使用此功能,我们将使用受实时 体育赛事 实时更新 API 启发的简单架构。前往 AppSync 控制台,使用以下架构创建新的 AppSync GraphQL API:

type Game {
    id: ID!
}

type GameEvent {
    id: ID!
    game: Game
    player: Player
    createdAt: AWSDateTime!
}

type Player {
    id: ID!
    stats: Stats
}

type Stats {
    points: Int
    assists: Int
}

type Query {
    getGameEvent(id: ID!): GameEvent
}

type Mutation {
    createGameEvent(input: CreateGameEventInput!): GameEvent
}

type Subscription {
    onCreateGameEvent(gameId: ID!, playerId: ID, points: Int, assists: Int): GameEvent
        @aws_subscribe(mutations: ["createGameEvent"])
}

input CreateGameEventInput {
    gameId: ID!
    playerId: ID!
    points: Int
    assists: Int
}

该架构允许你使用 createGameEvent 突变 创建游戏事件 ,并使用 onCreateGameEvent 订阅来订阅这些事件。 请注意, GameEvent 玩家 字段是一种复杂的嵌套类型。该 API 使用 NONE 解析器来发布数据而不将其保存到数据源。 createGameEvent 解析器连接到 NONE 解析器,只需在本地转发负载即可。

import { util } from '@aws-appsync/utils';

export function request(ctx) {
    const { gameId, playerId: id, assists, points } = ctx.args.input;
    const payload = {
        id: util.autoId(),
        createdAt: util.time.nowISO8601(),
        game: { id: gameId },
        player: { id, stats: { assists, points } },
    };
    return { payload };
}

export const response = (ctx) => ctx.result;

订阅 onCreateGameEvent 解析器也与 N ONE 解析器相关联。

import { util, extensions } from '@aws-appsync/utils';

export const request = (ctx) => ({ payload: null });

export function response(ctx) {
    const { playerId, assists, points } = ctx.args;
    const filter = { 'game.id': { eq: ctx.args.gameId } };
    const playerFilter = [];
    if (playerId) {
        playerFilter.push({
            'player.id': { eq: playerId },
            or: [
                { ...(points ? { 'player.stats.points': { ge: points } } : null) },
                { ...(assists ? { 'player.stats.assists': { ge: assists } } : null) },
            ],
        });
    }
    filter.or = playerFilter;
    console.log('filter:', filter);
    extensions.setSubscriptionFilter(util.transform.toSubscriptionFilter(filter));
    return null;
}

解析器响应处理程序设置订阅,当特定游戏( GameID )的游戏事件发生时,该订阅会通知连接的客户端。 或者,如果提供了 PlayerID ,解析器会进一步过滤涉及指定玩家的事件,并有条件地过滤助攻和得分。 请注意,使用 e xtensions.setSubscriptionFilter 来设置过滤器 ,并使用 util.torns form.toSubscriptionFilter 将过滤器转换为适当的格式

您可以通过 AppSync 控制台的查询编辑器测试您的订阅。首先,建立订阅。在下面的示例中,你订阅了一场假设的 NBA 比赛,收听达拉斯和密尔沃基之间的比赛事件,这场比赛涉及卢卡·唐西奇,他们至少获得 30 分或 10 次助攻。

subscription OnGameEvent {
  onCreateGameEvent(gameId: "DALvsMIL", playerId: "LUKADONCIC77", points: 30, assists: 10) {
    game {
      id
    }
    createdAt
    id
    player {
      id
      stats {
        assists
        points
      }
    }
  }
}

在您的 Amazon CloudWatch Logs 中,您可以看到带有已配置过滤器的日志行,其中包括嵌套规则(从订阅解析器代码中记录):

{
    "game.id": { "eq": "DALvsMIL" },
    "or": [
        {
            "player.id": { "eq": "LUKADONCIC77" },
            "or": [
                { "player.stats.points": { "ge": 30 } },
                { "player.stats.assists": { "ge": 10 } }
            ]
        }
    ]
}

要测试订阅,请在新选项卡中打开查询编辑器的另一个实例,然后发送一个变体:

mutation NewGameEvent {
  createGameEvent(input: {gameId: "DALvsMIL", playerId: "LUKADONCIC77", assists: 11, points: 33}) {
    createdAt
    game {
      id
    }
    id
    player {
      id
      stats {
        assists
        points
      }
    }
  }
}

您可以更改游戏ID和相关玩家,以查看触发订阅的方式和时间。

使订阅无效

您可以使用嵌套过滤器使实时订阅失效。例如,假设你想在游戏结束时关闭所有活跃的订阅。 首先,更新您的 onCreateGameEven t 订阅响应处理程序,并在返回语句之前添加以下几行:

const invalidation = { 'game.id': { eq: ctx.args.gameId } };
extensions.setSubscriptionInvalidationFilter(util.transform.toSubscriptionFilter(invalidation));

这将在订阅中基于嵌套字段 gam e.id 创建失效过滤器。接下来,将 EndGame 突变添加到你的架构中:

type Mutation {
    createGameEvent(input: CreateGameEventInput!): GameEvent
    endGame(gameId: ID!): Game
}

使用以下代码为 EndGam e 创建解析器:

import { extensions } from '@aws-appsync/utils';
export function request(ctx) {
    return { payload: { id: ctx.args.gameId } };
}

export function response(ctx) {
    extensions.invalidateSubscriptions({
        subscriptionField: 'onCreateGameEvent',
        payload: { 'game.id': ctx.args.gameId },
    });
    return ctx.result;
}

当使用 游戏 ID 调用 End Game 突变时,解析器将使用该特定 ID 发送订阅失效请求。停止并重新启动您的订阅。然后,要使订阅失效,请使用 E ndGame 突变

mutation EndGame {
  endGame(gameId: "DALvsMIL") {
    id
  }
}

任何使用与该值匹配的失效过滤器的订阅都将终止并显示以下消息:

{
  "message": "Subscription complete."
}

结论

在这篇文章中,我们回顾了 AppSync 增强过滤器的新嵌套对象筛选功能。我们还展示了如何使用嵌套对象筛选来使订阅失效。要了解有关在自己的订阅中使用增强筛选功能的更多信息,请参阅 文档 教程 。您还可以在样本 库中找到易于使用的 示例 和指南 。


*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您发展海外业务和/或了解行业前沿技术选择推荐该服务。