1.0.0 • Published 6 months ago

@ts-private/federated-graphql-ws v1.0.0

Weekly downloads
-
License
MIT
Repository
github
Last release
6 months ago

federated-graphql-ws

Utilities collection that supports a smooth implementation of GraphQL Subscriptions with GraphQL Apollo Federation. The utilities are designed to be used with graphql-ws and Apollo Gateway.

Installation

npm i @ts-private/federated-graphql-ws

or

yarn add @ts-private/federated-graphql-ws

Usage with Apollo Gateway

  • ApolloGateway
const { ApolloGateway } = require('@apollo/gateway'),
  { ApolloServer } = require('@apollo/server')

async function initializeApolloGateway(httpServer) {
  const gateway = new ApolloGateway({
    serviceHealthCheck: true
  })

  gateway.onSchemaLoadOrUpdate(gatewaySchema => {
    schema = gatewaySchema.apiSchema
  })

  console.info('Creating Apollo Server...')
  const server = new ApolloServer({
    gateway
  })

  await server.start()

  httpServer.on('request', app.callback())

  return { schema, gateway, httpServer }
}
  • graphql-ws server
const { Server } = require('ws'),
  { useServer } = require('graphql-ws/lib/use/ws'),
  { execute } = require('graphql'),
  { wsExecutor, parseSubscriptionOperation, aggregateNonPayloadData } = require('@ts-private/federated-graphql-ws')

function initializeWsServer({ schema, gateway, httpServer }) {
  console.info('Creating Subscription Server...')
  useServer(
    {
      execute,
      subscribe: wsExecutor,
      onSubscribe: async (ctx, { payload }) => {
        return await parseSubscriptionOperation({ payload, gateway, schema })
      },
      onNext: aggregateNonPayloadData(gateway),
      context: (ctx, _msg, _args) => ctx
    },
    new Server({
      server: httpServer,
      path: '/graphql'
    })
  )
}
  • Running the server
const http = require('http')

console.info('Creating HTTP server...')
process.httpServer = http.createServer()
initializeApolloGateway(process.httpServer).then(ctx => {
  initializeWsServer(ctx)
  const port = process.env.PORT || 4000
  process.httpServer.listen(port, () => {
    console.log(`🛸 Gateway ready at http://localhost:${port}/graphql`)
    console.log(`🚀 Subscriptions ready at ws://localhost:${port}/graphql`)
  })
})