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

Resolve another subgraph's fields

Resolve the same entity field from different subgraphs


By default, exactly one resolves each in your , with exceptions like @key . Sometimes, multiple can resolve a specific entity field because they share access to a data store. For example, an Inventory subgraph and a Products subgraph might both have access to the same database that stores all product-related data.

This guide explains how you can enable different subgraphs to resolve the same field as a performance optimization.

Enable subgraphs to resolve the same field

You can optionally enable multiple subgraphs to resolve a particular entity field. Then, when the plans a 's execution, it looks at which fields are available from each subgraph. The router can optimize performance by executing the query across the fewest subgraphs needed.

To do this, use one of the following :

  • @shareable
  • @provides

Which you use depends on the following logic:

Always
Only certain query paths
Can my subgraph always resolve this field,
or only from certain query paths?
@shareable
@provides

If you aren't sure whether your subgraph can always resolve a field, see Using @provides for an example of a subgraph that can't.

Ensure resolver consistency

If multiple subgraphs can resolve a field, ensure each subgraph's behaves identically for that field. Otherwise, queries might return inconsistent results to clients depending on which subgraph resolves the field.

This consistency is especially important to enforce when changing an existing resolver. Clients might observe inconsistent results if you don't make the resolver changes to each subgraph simultaneously.

Common inconsistent resolver behaviors to look out for include:

  • Returning a different default value
  • Throwing different errors in the same scenario

Using @shareable

NOTE

Before using @shareable, see Ensure resolver consistency.

The @shareable directive indicates that more than one subgraph can resolve a particular field. You can use it like so:

Products subgraph
type Product @key(fields: "id") {
id: ID!
name: String! @shareable
price: Int
}
Inventory subgraph
type Product @key(fields: "id") {
id: ID!
name: String! @shareable
inStock: Boolean!
}

In this example, both the Products and Inventory subgraphs can resolve Product.name. That means queries including Product.name can sometimes be resolved with fewer subgraph fetches.

NOTE

If a field is marked @shareable in any subgraph, it must be marked @shareable or @external in every subgraph that defines it. Otherwise, fails.

Using @provides

NOTE

Before using @provides, see Ensure resolver consistency.

The @provides directive indicates that a particular field can be resolved by a subgraph at a particular query path. For example, suppose the Inventory subgraph can resolve Product.name, but only when that product is part of an InStockCount. You can indicate this like so:

Inventory subgraph
type InStockCount {
product: Product! @provides(fields: "name")
quantity: Int!
}
type Product @key(fields: "id") {
id: ID!
name: String! @external
inStock: Boolean!
}

Notice the Inventory subgraph uses two directives:

  • The @provides directive tells the router, "This subgraph can resolve the name of any Product object returned by InStockCount.product."
  • The @external directive tells the router, "This subgraph can't resolve the name of a Product object, except wherever indicated by @provides."

Rules for using @provides

NOTE

Violating any of these rules causes composition to fail.

  • If a subgraph @provides a field that it can't always resolve, the subgraph must mark that field as @external and must not mark it as @shareable.
    • Remember, a @shareable field can always be resolved by a particular subgraph, which removes the need for @provides.
  • To include a field in a @provides directive, that field must be marked as @shareable or @external in every subgraph that defines it.
Previous
Contribute and Reference Entity Fields
Next
Use Contexts to Share Data
Rate articleRateEdit on GitHubEditForumsDiscord

© 2024 Apollo Graph Inc., d/b/a Apollo GraphQL.

Privacy Policy

Company