Join us from October 8-10 in New York City to learn the latest tips, trends, and news about GraphQL federation and API platform engineering.Join us for GraphQL Summit 2024 in NYC
Docs
Start for Free

Deferring Query Response Data

Using the @defer directive


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

RouterClientRouterClientResolves non-deferredfieldsResolves deferredfieldsSends a query thatdefers some fieldsReturns data fornon-deferred fieldsReturns data fordeferred fields

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

How do I defer fields in a query?

NOTE

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

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

If you're using a defer-compatible client, you apply the @defer to in your queries to specify which fields 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 supergraph's router receives this query, it defers every in these fragments that it's able to.

Which fields can my router defer?

Your supergraph's router can defer the following fields in your schema:

  • Root fields of the Query type (along with their subfields)
  • of any type (along with their subfields)
    • Deferring entity fields 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 router can defer any field of your schema's Query type, along with any subfields of those fields:

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

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

Entity fields

Your router supports deferring fields of the special in your supergraph called entities.

Entities are object types that often define their fields across multiple (but they don't have to). You can identify an entity by its use of the @key directive. In the example 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 subgraphs, and this is what enables your router to defer their fields: the router can send a followup query to a subgraph to fetch any entity fields that it doesn't fetch initially.

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

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

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

NOTE

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

Defining entities in your subgraphs

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

To learn about creating entities, see this article.

Requirements for @defer

To use @defer successfully, your supergraph 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 fields).

General requirements

Entity-specific requirements

Previous
Safelisting with Persisted Queries
Next
GraphQL Subscriptions
Rate articleRateEdit on GitHubEditForumsDiscord

© 2024 Apollo Graph Inc.

Privacy Policy

Company