Using Modern Directives (defer, stream)

1. Understanding @defer Directive

AspectDetail
StatusIncremental Delivery EXPERIMENTAL
EffectServer returns initial payload, then patches for deferred fragments
Transportmultipart/mixed HTTP response
Argslabel: String, if: Boolean

2. Using @defer for Slow Fields

Example: Defer slow nested data

query Profile {
  user(id: "1") {
    id
    name
    ... @defer(label: "stats") {
      activityStats { posts comments likes }
    }
  }
}

3. Understanding @stream Directive

ArgDetail
initialCountHow many items in first payload
labelIdentify the patch
ifConditional streaming

4. Using @stream for Large Lists

Example: Stream comments

query Feed {
  posts {
    id
    title
    comments @stream(initialCount: 5) {
      id
      body
    }
  }
}

5. Implementing Incremental Delivery

ServerSupport
graphql-yogaBuilt-in
graphql-helixBuilt-in
Apollo Server 4Behind flag EXPERIMENTAL
graphql-jsexperimentalExecuteIncrementally

6. Handling Deferred Responses

Example: Initial then incremental payloads

// First payload
{ "data": { "user": { "id": "1", "name": "Ada" } }, "hasNext": true }

// Subsequent
{ "incremental": [{ "path": ["user"], "data": { "activityStats": { ... } } }], "hasNext": false }

7. Handling Streamed Responses

Payload FieldMeaning
itemsNew list elements
pathWhere to merge in original response
hasNexttrue while more chunks coming

8. Combining @defer and @stream

Example: Defer fragment containing streamed list

query Dashboard {
  ... @defer {
    feed {
      items @stream(initialCount: 3) { id title }
    }
  }
}

9. Understanding Browser Support

ClientSupport
Apollo Client 3.7+Yes — multipart subscription transport
Relay 14+Yes — native @defer/@stream
urqlLimited via @urql/exchange-multipart-fetch
BrowsersNeed fetch + ReadableStream (modern only)

10. Using with Apollo Client

Example: Apollo Client setup

import { ApolloClient, InMemoryCache, HttpLink } from "@apollo/client";

const client = new ApolloClient({
  link: new HttpLink({ uri: "/graphql" }),
  cache: new InMemoryCache(),
});

// useQuery returns initial + incremental updates automatically