Docs
Launch GraphOS Studio

Deferring query response data with GraphOS

Using the @defer directive


With , your 's can defer returning data for certain s in your . This enables a querying client to receive non-deferred data more quickly, because the can return it immediately instead of waiting for all response data to be ready:

ClientRouterSends a query thatdefers some fieldsResolves non-deferredfieldsReturns data fornon-deferred fieldsResolves deferredfieldsReturns data for deferred fieldsClientRouter

Both cloud supergraphs and self-hosted supergraphs support deferring s with the . Additionally, this feature is compatible with all supported subgraph libraries, because the logic resides entirely within the !

How do I defer fields in a query?

⚠️ Deferring query fields requires a defer-compatible client library. These libraries support receiving query data incrementally via multipart HTTP responses.

Defer support is currently available in Apollo Client for Web and Kotlin (experimental).

If you're using a defer-compatible client, you apply the @defer to s in your queries to specify which s you want to defer:

query GetTopProductsAndReviews {
topProducts {
id
name
# You always apply @defer to a fragment, not to individual fields
... @defer {
reviews {
score
}
}
}
}

When your 's receives this query, it defers every in these s that it's able to.

Which fields can my router defer?

Your 's can defer the following s in your :

  • Root s of the Query type (along with their subs)
  • s of any entity type (along with their subs)
    • Deferring entity s is extremely powerful but requires some setup if you aren't using entities already. This is covered in more detail below.

See below for more information on each of these.

Query fields

Your can defer any of your 's Query type, along with any subs of those fields:

query GetUsersAndDeferProducts {
users {
id
}
... @defer {
products {
id
}
}
}

With the query above, the first returns a list of User IDs, then later completes the response with a list of Product IDs.

Entity fields

Your supports deferring s of the special s in your called entities.

Entities are s that often define their s across multiple s (but they don't have to). You can identify an entity by its use of the @key . In the example s below, the Product type is an entity:

Products subgraph
type Product @key(fields: "id") {
id: ID!
name: String!
price: Int!
}
type Query {
topProducts: [Product!]!
}
Reviews subgraph
type Product @key(fields: "id") {
id: ID!
reviews: [Review!]!
}
type Review {
score: Int!
}

Entities are query entry points into your s, and this is what enables your to defer their s: the router can send a followup query to a to fetch any entity s that it doesn't fetch initially.

Here's an example query that defers entity s using the s above:

query GetProductsAndDeferReviews {
topProducts {
id
name
... @defer {
reviews {
score
}
}
}
}

To handle this query, the first resolves and returns a list of Product objects with their IDs and names. Later, the completes the response by returning review scores for each of those products.

It doesn't matter which defines a particular entity ! Queries can defer entity fields that are defined across any number of different subgraphs.

Defining entities in your subgraphs

If your s don't yet include any entities, you need to define some before clients can start deferring their s in queries.

To learn about creating entities, see this article.

Requirements for @defer

To use @defer successfully, your and its clients must meet the requirements listed below. These requirements are divided between general requirements (requirements for using @defer at all) and entity-specific requirements (additional requirements for using @defer with entity s).

General requirements

Entity-specific requirements

Previous
AWS Lattice troubleshooting
Next
GraphQL subscriptions
Edit on GitHubEditForumsDiscord