Skip to content
GraphQL with subscriptions in AWS Lambda
TypeScript HTML JavaScript
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.

README.md

AWS Lambda GraphQL with subscriptions

CircleCI Version

This library is not ready for production and is not really as robust as subscriptions-transport-ws

This library uses typescript so for now use types as documentation

This library uses yarn and yarn workspaces so only yarn.lock is commited.

Motivation

This library is created because I wanted to try if it's possible to implement GraphQL server with subscriptions in AWS Lambda. And yes it is possible with AWS API Gateway v2.

Table of contents

Infrastructure

Current infrastructure is implemented using AWS Lambda + AWS API Gateway v2 + AWS DynamoDB (with DynamoDB streams). But it can be implemented using various solutions (Kinesis, etc) because it's written to be modular.

Usage (server)

npm install aws-lamda-graphql apollo-link graphql graphql-subscriptions
# or
yarn add aws-lambda-graphql apollo-link graphql graphql-subscriptions

Implement your simple server

const {
  createDynamoDBEventProcessor,
  createWsHandler,
  DynamoDBConnectionManager,
  DynamoDBEventStore,
  DynamoDBSubscriptionManager,
  PubSub,
} = require('aws-lambda-graphql');
import { makeExecutableSchema } from 'graphql-tools';

// this only processes AWS Api Gateway v2 events
// if you want to process HTTP too, use createHttpHandler
// or you can use both, see chat-example-server

// instantiate event store
// by default uses Events table (can be changed)
const eventStore = new DynamoDBEventStore();
const pubSub = new PubSub({ eventStore });
const subscriptionManager = new DynamoDBSubscriptionManager();
const connectionManager = new DynamoDBConnectionManager({
  subscriptions: subscriptionManager,
});

const schema = makeExecutableSchema({
  typeDefs: /* GraphQL */ `
    type Mutation {
      publish(message: String!): String!
    }

    type Query {
      dummy: String!
    }

    type Subscription {
      messageFeed: String!
    }
  `,
  resolvers: {
    Query: {
      dummy: () => 'dummy',
    },
    Mutation: {
      publish: async (rootValue, { message }) => {
        await pubSub.publish('NEW_MESSAGE)', { message });

        return message;
      },
    },
    Subscription: {
      messageFeed: {
        // rootValue is same as object published using pubSub.publish
        resolve: rootValue => rootValue.message,
        subscribe: pubSub.subscribe('NEW_MESSAGE'),
      },
    },
  },
});

const eventProcessor = createDynamoDBEventProcessor({
  connectionManager,
  schema,
  subscriptionManager,
});
const wsHandler = createWsHandler({
  connectionManager,
  schema,
  subscriptionManager,
  // validationRules
});

// use these handlers from your lambda and map them to
// api gateway v2 and DynamoDB events table
module.exports.consumeWsEvent = wsHandler;
module.exports.consumeDynamoDBStream = eventProcessor;

Usage (client)

yarn add aws-lambda-ws-link graphql
# or
npm install aws-lambda-ws-link graphql

Implement your simple client

import { Client, WebSocketLink } from 'aws-lambda-ws-link';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { ApolloClient } from 'apollo-client';

const wsClient = new Client({
  uri: 'ws://localhost:8000',
});
const link = new WebSocketLink(client);
const client = new ApolloClient({
  cache: new InMemoryCache(),
  link,
});

// ...

Examples

  • Chat App - React app
  • Chat Server
    • contains AWS Lambda that handles HTTP, WebSocket and DynamoDB streams
    • also includes serverless.yaml file for easy deployment

Contributing

Running tests locally:

yarn install
yarn test

This project uses TypeScript for static typing and TSLint for linting. You can get both of these built into your editor with no configuration by opening this project in Visual Studio Code, an open source IDE which is available for free on all platforms.

License

MIT

You can’t perform that action at this time.