Skip to content

Commit

Permalink
Reuse named fragment in subgraphs even if they only apply partially (#…
Browse files Browse the repository at this point in the history
…2639)

The focus of the code reusing fragment has been thus far on making
that if a given named fragment can be used in a given selection set,
then the code finds it. But in practice, the named fragments we try
to reuse are those of the input query, so defined against the
supergraph API schema, while we're trying to reuse them on subgraph
fetches, so the fragment may be defined on a type that a subgraph
does know, or request fields the subgraph does not define.

Currently, when asking if a given named fragment can be used against
a given subgraph, we only keep fragment that _fully_ apply to that
subgraph (that is, only if everything the fragment queries exists
in the subgraph).

This does limit the usefulness of named fragment reuse however, as one
of the point of federation is that each subgraph defines a subset
of the full supergraph API.

This commit improves this by instead computing the subset of each
named fragment that do apply to a given subgraph, and define the
fragment as only that fragment for the subgraph.

Note that it does so, this commit do not try reusing a named fragment
against a subgraph if the subset of the fragment on the subgraph
comes to only a single leaf field. This avoids spending time trying
to reuse a fragment that ends up being just:
```graphql
fragment MySuperFragment on X {
  __typename
}
```
or even:
```graphql
fragment MySuperFragment on X {
 id
}
```
as those aren't productive (the goal of fragment reuse is to try to
make the subgraph fetches smaller, but it is small to just request
`id`, even 10 times, than to request 10 times `...MySuperFragment`).
  • Loading branch information
Sylvain Lebresne committed Jun 27, 2023
1 parent 191dea1 commit d60349b
Show file tree
Hide file tree
Showing 6 changed files with 875 additions and 74 deletions.
8 changes: 8 additions & 0 deletions .changeset/olive-bees-build.md
@@ -0,0 +1,8 @@
---
"@apollo/query-planner": patch
"@apollo/federation-internals": patch
"@apollo/gateway": patch
---

Try reusing named fragments in subgraph fetches even if those fragment only apply partially to the subgraph. Before this change, only named fragments that were applying entirely to a subgraph were tried, leading to less reuse that expected. Concretely, this change can sometimes allow the generation of smaller subgraph fetches.

19 changes: 13 additions & 6 deletions gateway-js/src/__tests__/buildQueryPlan.test.ts
Expand Up @@ -744,18 +744,21 @@ describe('buildQueryPlan', () => {

it(`should not get confused by a fragment spread multiple times`, () => {
const operationString = `#graphql
fragment Price on Product {
fragment PriceAndCountry on Product {
price
details {
country
}
}
query {
topProducts {
__typename
... on Book {
...Price
...PriceAndCountry
}
... on Furniture {
...Price
...PriceAndCountry
}
}
}
Expand All @@ -770,16 +773,20 @@ describe('buildQueryPlan', () => {
topProducts {
__typename
... on Book {
...Price
...PriceAndCountry
}
... on Furniture {
...Price
...PriceAndCountry
}
}
}
fragment Price on Product {
fragment PriceAndCountry on Product {
price
details {
__typename
country
}
}
},
}
Expand Down

0 comments on commit d60349b

Please sign in to comment.