Data source integrations for AWS AppSync events - AWS AppSync Events

Data source integrations for AWS AppSync events

With AWS AppSync Events, you can create event handlers that run custom business logic on AWS AppSync's JavaScript runtime. By configuring data source integrations, you can interact with external systems like Lambdafunctions, DynamoDB tables, or Amazon RDS Aurora databases.

Overview

You can integrate data sources in your channel namespaces to interact with DynamoDB tables and Lambda functions. Each integration requires implementing request and response functions. This topic explains how to configure and use data sources with event handlers.

For detailed information about data source configuration options, see Working with data sources for AWS AppSync Event APIs.

Handler structure

A handler that interacts with a data source has the following two functions:

  • Request — Defines the payload sent to the data source

  • Response — Defines the payload sent to the data source

Example Saving events to DynamoDB before broadcasting

The following example defines an onPublish handler that saves all published events to a messages_table in DynamoDB before forwarding them to be broadcast.

import * as ddb from `@aws-appsync/utils/dynamodb` const TABLE = 'messages_table' export const onPublish = { request(ctx) { const channel = ctx.info.channel.path return ddb.batchPut({ tables: { [TABLE]: ctx.events.map(({ id, payload }) => ({ channel, id, ...payload })), }, }) }, response(ctx) { console.log(`Batch Put result:`, ctx.result.data[TABLE]) return ctx.events } }
Note

You must return the list of events you want broadcasted in the response function.

Example Forward all events after accessing it from the data source
import * as ddb from `@aws-appsync/utils/dynamodb` const TABLE = 'messages_table' export const onPublish = { request(ctx) { const channel = ctx.info.channel.path return ddb.batchPut({ tables: { [TABLE]: ctx.events.map(({ id, payload }) => ({ channel, id, ...payload })), }, }) }, response: (ctx) => ctx.events // forward all events }

onSubscribe handler

Use the onSubscribe handler to process subscription requests.

Example Logging subscriptions to an RDS database
import { insert, createPgStatement as pg } from '@aws-appsync/utils/rds' export const onSubscribe = { request(ctx) { const values = { channel: ctx.info.channel.path, identity: ctx.identity } return pg(insert({table: 'subs', values})) }, response(ctx) {} // Required empty function }
Note

You must provide a response function, which can be empty if no other action is required.

Example Granting access based on a channel path
import { select, createPgtatement as pg, toJsonObject } from '@aws-appsync/utils/rds'; export const onSubscribe = { request(ctx) { const values = { channel: ctx.info.channel.path, identity: ctx.identity } return pg(insert({ select: 'subs', where: { channel: { eq: 'ALLOWED' }} })) }, response(ctx){ const { error, result } = ctx; if (error) { return util.error('db error') } const res = toJsonObject(result)[1][0]; if (!res.length) { // did not find the item, subscription is not authorized util.unauthorized() } } }
Example Skipping the data source

To skip the data source invocation at runtime use the runtime.earlyReturn utility. The earlyReturn operation returns the provided payload and skips the response function.

import * as ddb from `@aws-appsync/utils/dynamodb` export const onPublish = { request(ctx) { if (ctx.info.channel.segments.includes('private')) { // return early and do no execute the response. return runtime.earlyReturn(ctx.events) } const channel = ctx.info.channel.path const event = ctx.events[0] const key = { channel, id: event.payload.id } return ddb.put({ key, item: event.payload }) }, response: (ctx) => ctx.events // forward all events }