⚡️ Pro Feature ⚡️ This feature is bundled with GraphQL-Pro.

Use with GraphiQL

You can use @defer and @stream with GraphiQL, an in-browser IDE.

Using @defer with GraphiQL

Incremental responses

If you’re using the proposed incremental: ... response syntax (proposal, Ruby support), you’ll need a custom “fetcher” function to handle the incremental: ... part of the response. For example:

import { meros } from "meros"; // for handling multipart responses

const customFetcher = async function* (graphqlParams, fetcherOpts) {
  // Make the initial fetch
  var result = await fetch("/graphql", {
    method: "POST",
    body: JSON.stringify(graphqlParams),
    headers: {
      'content-type': 'application/json',
    }
  }).then((r) => {
    // Use meros to turn multipart responses into streams
    return meros(r, { multiple: true })
  })

  if (!isAsyncIterable(result)) {
    // Return plain responses as promises
    return result.json()
  } else {
    // Handle multipart responses one chunk at a time
    for await (const chunk of result) {
      yield chunk.map(part => {
        // Move the incremental part of the response into top-level
        // This assumes there's only one `incremental` entry
        // which is currently true for GraphQL-Pro's @defer implementation
        var newJson = {...part.body}
        if (newJson.incremental) {
          newJson.data = newJson.incremental[0].data
          newJson.path = newJson.incremental[0].path
          delete newJson.incremental
        }
        return newJson
      });
    }
  }
}

// Helper for checking for a multipart response:
function isAsyncIterable(input) {
  return (
      typeof input === "object" &&
      input !== null &&
      (
        input[Symbol.toStringTag] === "AsyncGenerator" ||
        (Symbol.asyncIterator && Symbol.asyncIterator in input)
      )
    );
}

Hopefully a new GraphiQL version will support this out of the box; follow the issue on GitHub.