Docs
Launch GraphOS Studio

Deferring query response data with GraphOS

Using the @defer directive


With GraphOS, your supergraph's router can defer returning data for certain fields in your schema. This enables a querying 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:

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 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?

⚠️ 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 directive to fragments 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 field 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)
  • Fields of any entity 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 object types in your supergraph called entities.

Entities are object types that often define their fields across multiple subgraphs (but they don't have to). You can identify an entity by its use of the @key directive. In the example subgraph schemas 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.

It doesn't matter which subgraph 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
Self-hosted routing
Next
Platform API
Edit on GitHubEditForumsDiscord