On this page

Incremental Delivery over HTTP

Use Incremental Delivery over HTTP for GraphQL subscriptions with Hive Router, based on the official GraphQL over HTTP spec RFC.

Subgraphs

Subgraphs don’t require any special configuration to use Incremental Delivery. When the router connects to a subgraph for a subscription, it will automatically negotiate Incremental Delivery if the subgraph supports it. The router prefers multipart first, then falls back to SSE.

Clients

To use Incremental Delivery, send requests with the following Accept header:

Accept: multipart/mixed

The router responds with multipart HTTP responses conforming to the Official GraphQL over HTTP Incremental Delivery over HTTP RFC.

If an error occurs, the router emits an error event and completes the stream. If the requested subscription transport is not supported, the router returns 406 Not Acceptable.

Try It

curl 'http://localhost:4000/graphql' \
  -H 'accept: multipart/mixed' \
  --json '{
    "query": "subscription {
      reviewAdded {
        body
        rating
        product {
          name
        }
        author {
          name
        }
      }
    }"
  }'

This command creates an HTTP multipart request and keeps an open connection that receives new subscription data in response “chunks”:

---
content-type: application/json

{"payload":{"data":{"reviewAdded":{"body":"Great product!","rating":5,"product":{"name":"Croissant"},"author":{"name":"Alice"}}}}}
---
content-type: application/json

{"payload":{"data":{"reviewAdded":{"body":"Could be better","rating":3,"product":{"name":"Baguette"},"author":{"name":"Bob"}}}}}
---
content-type: application/json

{"payload":{"data":{"reviewAdded":{"body":"Excellent quality","rating":5,"product":{"name":"Croissant"},"author":{"name":"Charlie"}}}}}
-----

This example subscription emits three events and then closes the connection. Notice how the product and author fields are automatically resolved from their respective subgraphs.

Apollo Client

Relay

meros is a fast utility that makes reading multipart responses simple. It works in both the browser and Node.js.

Using it with Relay is quite straightforward, here’s an example setup:

npm install meros
import { meros } from "meros/browser";
import {
  GraphQLResponse,
  Network,
  Observable,
  RequestParameters,
  Variables,
} from "relay-runtime";

// Supports both queries/mutations and subscriptions.
function fetchOrSubscribe(operation: RequestParameters, variables: Variables) {
  return Observable.create<GraphQLResponse>((sink) => {
    const ctrl = new AbortController();

    (async () => {
      const parts = await fetch("http://localhost:4000/graphql", {
        signal: ctrl.signal,
        method: "POST",
        body: JSON.stringify({
          query: operation.text,
          variables,
        }),
        headers: {
          "content-type": "application/json",
          accept: "application/json, multipart/mixed",
        },
      }).then(meros);

      if (parts instanceof Response) {
        // query/mutation
        return parts.json();
      }

      // subscription
      for await (const part of parts) {
        sink.next(part);
      }
    })()
      .then(() => sink.complete())
      .catch((error) => sink.error(error));

    return () => ctrl.abort();
  });
}

export const network = Network.create(fetchOrSubscribe, fetchOrSubscribe);

urql