Get Started

Get Started

Zero-dependency, HTTP/1 safe, simple, GraphQL over Server-Sent Events spec server and client.

For detailed documentation and API reference, check out the documentation page. If you need short and concise code snippets for starting with common use-cases, the recipes page is the right place for you.

Install

npm i graphql-sse

Create a GraphQL schema

import { GraphQLSchema, GraphQLObjectType, GraphQLString } from 'graphql';
 
/**
 * Construct a GraphQL schema and define the necessary resolvers.
 *
 * type Query {
 *   hello: String
 * }
 * type Subscription {
 *   greetings: String
 * }
 */
const schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    name: 'Query',
    fields: {
      hello: {
        type: GraphQLString,
        resolve: () => 'world',
      },
    },
  }),
  subscription: new GraphQLObjectType({
    name: 'Subscription',
    fields: {
      greetings: {
        type: GraphQLString,
        subscribe: async function* () {
          for (const hi of ['Hi', 'Bonjour', 'Hola', 'Ciao', 'Zdravo']) {
            yield { greetings: hi };
          }
        },
      },
    },
  }),
});

Start the server

With http

import http from 'http';
import { createHandler } from 'graphql-sse/lib/use/http';
import { schema } from './previous-step';
 
// Create the GraphQL over SSE handler
const handler = createHandler({ schema });
 
// Create an HTTP server using the handler on `/graphql/stream`
const server = http.createServer((req, res) => {
  if (req.url.startsWith('/graphql/stream')) {
    return handler(req, res);
  }
  res.writeHead(404).end();
});
 
server.listen(4000);
console.log('Listening to port 4000');

With http2

đź’ˇ

Browsers might complain about self-signed SSL/TLS certificates. Help can be found on StackOverflow.

$ openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' \
  -keyout localhost-privkey.pem -out localhost-cert.pem
import http2 from 'http2';
import { createHandler } from 'graphql-sse/lib/use/http2';
import { schema } from './previous-step';
 
// Create the GraphQL over SSE handler
const handler = createHandler({ schema });
 
// Create an HTTP/2 server using the handler on `/graphql/stream`
const server = http2.createSecureServer(
  {
    key: fs.readFileSync('localhost-privkey.pem'),
    cert: fs.readFileSync('localhost-cert.pem'),
  },
  (req, res) => {
    if (req.url.startsWith('/graphql/stream')) {
      return handler(req, res);
    }
    return res.writeHead(404).end();
  },
);
 
server.listen(4000);
console.log('Listening to port 4000');

With express

import express from 'express'; // yarn add express
import { createHandler } from 'graphql-sse/lib/use/express';
import { schema } from './previous-step';
 
// Create the GraphQL over SSE handler
const handler = createHandler({ schema });
 
// Create an express app
const app = express();
 
// Serve all methods on `/graphql/stream`
app.use('/graphql/stream', handler);
 
server.listen(4000);
console.log('Listening to port 4000');

With fastify

import Fastify from 'fastify'; // yarn add fastify
import { createHandler } from 'graphql-sse/lib/use/fastify';
 
// Create the GraphQL over SSE handler
const handler = createHandler({ schema });
 
// Create a fastify app
const fastify = Fastify();
 
// Serve all methods on `/graphql/stream`
fastify.all('/graphql/stream', handler);
 
fastify.listen({ port: 4000 });
console.log('Listening to port 4000');

With Koa

import Koa from 'koa'; // yarn add koa
import mount from 'koa-mount'; // yarn add koa-mount
import { createHandler } from 'graphql-sse/lib/use/koa';
import { schema } from './previous-step';
 
// Create a Koa app
const app = new Koa();
 
// Serve all methods on `/graphql/stream`
app.use(mount('/graphql/stream', createHandler({ schema })));
 
app.listen({ port: 4000 });
console.log('Listening to port 4000');

With Deno

import { serve } from 'https://deno.land/std/http/server.ts';
import { createHandler } from 'https://esm.sh/graphql-sse/lib/use/fetch';
import { schema } from './previous-step';
 
// Create the GraphQL over SSE native fetch handler
const handler = createHandler({ schema });
 
// Serve on `/graphql/stream` using the handler
await serve(
  (req: Request) => {
    const [path, _search] = req.url.split('?');
    if (path.endsWith('/graphql/stream')) {
      return handler(req);
    }
    return new Response(null, { status: 404 });
  },
  {
    port: 4000, // Listening to port 4000
  },
);

With Bun@>=0.8.0

import { createHandler } from 'graphql-sse/lib/use/fetch'; // bun install graphql-sse
import { schema } from './previous-step';
 
// Create the GraphQL over SSE native fetch handler
const handler = createHandler({ schema });
 
// Serve on `/graphql/stream` using the handler
export default {
  port: 4000, // Listening to port 4000
  async fetch(req) {
    const [path, _search] = req.url.split('?');
    if (path.endsWith('/graphql/stream')) {
      return await handler(req);
    }
    return new Response(null, { status: 404 });
  },
};

Use the client

import { createClient } from 'graphql-sse';
 
const client = createClient({
  // singleConnection: true, preferred for HTTP/1 enabled servers and subscription heavy apps
  url: 'http://localhost:4000/graphql/stream',
});
 
// query
(async () => {
  const query = client.iterate({
    query: '{ hello }',
  });
 
  const { value } = await query.next();
  expect(value).toEqual({ hello: 'world' });
})();
 
// subscription
(async () => {
  const subscription = client.iterate({
    query: 'subscription { greetings }',
  });
 
  for await (const event of subscription) {
    expect(event).toEqual({ greetings: 'Hi' });
 
    // complete a running subscription by breaking the iterator loop
    break;
  }
})();