AWS recently launched AppSync which is in public preview. I have yet to try it my self but it is significantly easier to setup than this package for graphql subscriptions. It also has cool features such as offline support and autoprovisioning of dynamodb tables based on your graphql schema.
(Work in progress!) Adapted from the Apollo subscriptions-transport-ws to support serverless GraphQL queries, mutations and subscriptions using AWS IoT websockets, lambda functions and an interface to your db of choice.
The manager publishes all socket messages to ${appPrefix}/in/clientId
, where clientId
is the unique identifier per client connected on AWS IoT
- For queries / mutations the manager immediately publishes the result upon processing the query.
- For subscriptions the following process occurs:
- Validate subscription with GraphQLSchema
- Store subscription information in DB. You provide the function to store a new subscription to the db. The addSubscription must return a promise on completion. The input parameter to this function is of the following format:
interface Subscription {
clientId: string;
query: string;
subscriptionName: string;
subscriptionId: string;
variableValues: { [key: string]: any };
}
- The GraphQLServer Package exports a PubSub class which is used to publish a new message. The PubSub class has a publish method which invokes the SubscriptionPublisherFunction. In your GraphQL Schema you invoke the publish method in the same way as you would if you were using the 'servered' subscriptions transport. The method returns a promise to ensure completion.
return pubsub.publish('NEW_TODO', { teamTodoAdded: input }).then(_ => {...});
- You are also required to provide a removeSubscriptionFunction that returns a promise on completion. The parameters to this function which are provided by this server package will be subscriptionName and clientId. We recommend having and index to retrieve a subscription based on those properties.
The publisher has one public method, executeQueriesAndSendMessages
, which takes an array of subscriptions in the same format as they were stored, executes the queries and then publishes the result to the active subscribers. This method returns a promise to ensure completion.
The triggerNameToSubscriptionNamesMap
and the triggerNameToFilterFunctionsMap
are defined in your own lambda function before invoking the publisher.
- Your application Subscription Publisher will get triggerName and payload in the event object.
- Use the
triggerNameToSubscriptionNamesMap
to identify all the subscriptionNames that you need to retrieve subscription rows for. - Retrieve subscriptions from the db. For each subscription pass in the array of subscription rows to the
executeQueriesAndSendMessages
. - Execute the filterFunction for the triggerName on each row.
- For those rows that return true in the filter function, you can run the
executeQueriesAndSendMessages
with an array of subscriptions and payload as the parameters. - You can choose to run this function in batches as per your application logic.
The database choice and how you choose to batch has been purposely left to the application rather than this helper package for reusability.
-
We recommend using the AWS IoT disconnect lifecycle event to remove active subscriptions from a clientId. See Demo Code for an example of a pruner on the aws iot disconnect event as well as a full working demo.
-
For scale you can publish AWS IoT events to a Kinesis stream which then invokes your SubscriptionManager lambda function