We use machine learning technology to do auto-translation. Click "English" on top navigation bar to check Chinese version.
Amazon Web Services AppSync WebSockets-based subscriptions for real-time updates now support nested filtering
Amazon Web Services AppSync is a fully managed service that enables developers to build digital experiences based on real-time data. With AppSync, you can configure data sources to push and publish real-time data updates to subscribed clients. AppSync handles connection management, scalability, fan-out and broadcasting, allowing you to focus on your application business needs instead of managing complex infrastructure. With AppSync, developers can easily specify filtering rules for their subscriptions to target specific connected clients based on the published data.
Today, AppSync introduces support for filtering on nested schema fields in
Getting started
To show how you can start using this feature in your own application, we will use a simple schema inspired by the
The schema allows you to create game events with the createGameEvent
mutation, and to subscribe to these events with the onCreateGameEvent
subscription. Note that GameEvent
has a player
field that is a complex nested type. The API uses a NONE
resolver that publishes data without saving it to a data source. The createGameEvent
resolver is attached to the NONE resolver and simply forwards the payload locally.
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;
The subscription onCreateGameEvent
resolver is associated with a NONE
resolver as well.
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;
}
The resolver response handler sets up a subscription that notifies connected clients when a game event for a specific game ( gameId
) has happened. Optionally, if the playerId
is provided, the resolver further filters for events that involve the specified player and conditionally filters on assists
and points
. Note the use of extensions.setSubscriptionFilter
to set up the filter, and util.transform.toSubscriptionFilter
to transform the filter to the appropriate format.
You can test your subscription from the AppSync console Query editor. First, establish the subscription. In the example below, you subscribe to an hypothetical NBA game, listening for game events between Dallas and Milwaukee, that involves Luka Doncic where they have at least 30 points or 10 assists.
In your Amazon CloudWatch Logs, you can see the log line with the configured filter that includes the nested rules (logged from the subscription resolver code):
To test the subscription, open another instance of the Query Editor in a new tab, and send a mutation:
You can make changes to the game ID and the involved player to see how and when the subscription is triggered.
Invalidating subscriptions
You can invalidate live subscriptions using nested filters. For example, let’s say you want to close all active subscriptions when a game ends. First, update your onCreateGameEvent
subscription response handler and add the following lines before the return
statement:
const invalidation = { 'game.id': { eq: ctx.args.gameId } };
extensions.setSubscriptionInvalidationFilter(util.transform.toSubscriptionFilter(invalidation));
This creates an invalidation filter in the subscription based on the nested field game.id
. Next, add the endGame
mutation to your schema:
Create a resolver for endGame
with the following code:
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;
}
When the endGame
mutation is called with a game ID, the resolver will send a subscription invalidation request with that specific ID. Stop and restart your subscription. Then, to invalidate a subscription, use the endGame
mutation:
Any subscription that uses an invalidation filter that matches the value is ended and the following message is shown:
Conclusion
In this post, we reviewed the new nested object filtering functionality for AppSync’s enhanced filters. We also showed how you can use nested object filtering to invalidate subscriptions. To learn more about using enhanced filtering in your own subscriptions, see the
The mentioned AWS GenAI Services service names relating to generative AI are only available or previewed in the Global Regions. Amazon Web Services China promotes AWS GenAI Services relating to generative AI solely for China-to-global business purposes and/or advanced technology introduction.