Channel namespace handlers and event processing - Amazon AppSync Events
Services or capabilities described in Amazon Web Services documentation might vary by Region. To see the differences applicable to the China Regions, see Getting Started with Amazon Web Services in China (PDF).

Channel namespace handlers and event processing

You can define event handlers on channel namespaces. Event handlers are functions that run on Amazon AppSync's JavaScript runtime and enable you to run custom business logic. You can use an event handler to process published events or process and authorize subscribe requests.

Using the onPublish event handler

The onPublish handler runs when events are received on a channel. The handler is called with the list of events. You can use the handler to either filter events or transform the events before they are sent to subscribed clients.

The default API behavior for the onPublish handler simply forwards all received events to be broadcast. The onPublish function receives a context object as its first argument.

The following code demonstrates the default behavior for the onPublish handler.

export function onPublish(ctx) { return ctx.events }

The Context object holds a list of events that are being handled. The type of each event is the following.

type IncomingEvent<T> = { /** * The ID associated with the event. */ id: String; /** * The payload associated with the event. */ payload: T; };

Processing events

The onPublish handler can act as an interceptor that can modify the list of events before they are broadcast. The following processing rules apply.

  • Your function must return an array.

  • Each event must match the Event type shape, and must have an ID that matches the ID of an incoming event.

  • Duplicate event IDs are not allowed.

  • Null objects in the returned array are dropped.

The type of outgoing events is the following.

export type OutgoingEvent<T extends any = any> = { /** * The ID associated with the event. */ id: String; /** * The payload associated with the event. Not required if an error is defined. */ payload?: T; /** * The error associated with the event. Populating this field with a value will * result in this error being marked as a failure and not propogated through the * system. */ error?: String; }

Filtering

You can filter out events, and only return the list of events you want subscribers to receive. For example, the handler below filters events and only forwards those that have “odds” greater than zero.

export function onPublish(ctx) { return ctx.events.filter((event) => event.payload.odds > 0) }

Transforming

You can also use a handler to transform events. Do this by mapping your events to the shape that you want. For example, the handler below formats each event to include a timestamp and changes the format of the message property.

import { util } from '@aws-appsync/utils' export function onPublish(ctx) { return ctx.events.map(event => ({ id: event.id, payload: { ...event.payload, message: event.payload.message.toUpperCase() timestamp: util.time.nowISO8601() } })) }
Note

Returning an event with an unknown id value results in an error.

Returning an error

To explicitly reject an event and notify the publisher that it was not accepted, add an error property containing an error message to the processed event. The following example, rejects any event that does not include a message property.

export function onPublish(ctx) { return ctx.events.map(event => { if (!event.payload.message || event.payload.message.length === 0) { event.error = "A message must be provided" } return event }) }

Using the onSubscribe event handler

The onSubscribe handler is called each time a client attempts to subscribe to a channel. You can use this handler to run custom business logic, such as logging specific information, or applying additional static authorization checks.

In the following example, the onSubscribe handler logs a message whan an admin user subscribes to a channel.

export function onSubscribe(ctx) { if (ctx.identity.groups.includes('admin')) { console.log(`Admin ${ctx.identity.sub} subscribed to ${ctx.channel}`) } }

You can reject a subscription by calling util.unauthorized(). The following onSubscribe handler restricts Amazon Cognito User Pool authenticated users to their own channel:

export function onSubscribe(ctx: Context) { if (ctx.info.channel.path !== `/messages/inbox/${ctx.identity.username}`) { console.log(`user ${ctx.identity.username} tried connecting to wrong channel: ${ctx.channel}`) util.unauthorized() }

Now clients can only subscribe to channels that match the pattern /messages/inbox/[username].