Skip to content

Commit d60349b

Browse files
author
Sylvain Lebresne
authored
Reuse named fragment in subgraphs even if they only apply partially (#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`).
1 parent 191dea1 commit d60349b

6 files changed

Lines changed: 875 additions & 74 deletions

File tree

.changeset/olive-bees-build.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@apollo/query-planner": patch
3+
"@apollo/federation-internals": patch
4+
"@apollo/gateway": patch
5+
---
6+
7+
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.
8+

gateway-js/src/__tests__/buildQueryPlan.test.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -744,18 +744,21 @@ describe('buildQueryPlan', () => {
744744

745745
it(`should not get confused by a fragment spread multiple times`, () => {
746746
const operationString = `#graphql
747-
fragment Price on Product {
747+
fragment PriceAndCountry on Product {
748748
price
749+
details {
750+
country
751+
}
749752
}
750753
751754
query {
752755
topProducts {
753756
__typename
754757
... on Book {
755-
...Price
758+
...PriceAndCountry
756759
}
757760
... on Furniture {
758-
...Price
761+
...PriceAndCountry
759762
}
760763
}
761764
}
@@ -770,16 +773,20 @@ describe('buildQueryPlan', () => {
770773
topProducts {
771774
__typename
772775
... on Book {
773-
...Price
776+
...PriceAndCountry
774777
}
775778
... on Furniture {
776-
...Price
779+
...PriceAndCountry
777780
}
778781
}
779782
}
780783
781-
fragment Price on Product {
784+
fragment PriceAndCountry on Product {
782785
price
786+
details {
787+
__typename
788+
country
789+
}
783790
}
784791
},
785792
}

0 commit comments

Comments
 (0)