Skip to content

Commit df5eb3c

Browse files
authored
fix: fix recursion logic in minimizeSelectionSet (#3158)
When generating fragments we were only "minimizing" subselections for fields and inline fragments that could be extracted. If inline fragment cannot be replaced with a fragment spread, we should still minimize its selection set as it potentially can be optimized as well.
1 parent ad94371 commit df5eb3c

File tree

3 files changed

+86
-5
lines changed

3 files changed

+86
-5
lines changed

.changeset/violet-cows-talk.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@apollo/federation-internals": patch
3+
---
4+
5+
Fix fragment generation recursion logic to apply minification on all subselections.

internals-js/src/__tests__/operations.test.ts

+77-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ describe('generate query fragments', () => {
9090
);
9191

9292
const withGeneratedFragments = operation.generateQueryFragments();
93-
console.log(withGeneratedFragments.toString());
9493
expect(withGeneratedFragments.toString()).toMatchString(`
9594
fragment _generated_onB1_0 on B {
9695
... on B {
@@ -113,6 +112,83 @@ describe('generate query fragments', () => {
113112
}
114113
`);
115114
});
115+
116+
test('minimizes all sub selections', () => {
117+
const schema = parseSchema(`
118+
type Query {
119+
foo: A
120+
}
121+
122+
type A {
123+
a1: Int
124+
a2: I
125+
}
126+
127+
interface I {
128+
i: Int
129+
}
130+
131+
type B implements I {
132+
i: Int
133+
b1: String
134+
b2: I
135+
}
136+
137+
type C implements I {
138+
i: Int
139+
c1: Int
140+
c2: String
141+
}
142+
`);
143+
144+
const operation = parseOperation(
145+
schema,
146+
`
147+
query Foo($flag: Boolean!) {
148+
foo {
149+
a1
150+
a2 {
151+
i
152+
... on B @include(if: $flag) {
153+
b1
154+
b2 {
155+
i
156+
... on C {
157+
c1
158+
c2
159+
}
160+
}
161+
}
162+
}
163+
}
164+
}
165+
`,
166+
);
167+
168+
const withGeneratedFragments = operation.generateQueryFragments();
169+
expect(withGeneratedFragments.toString()).toMatchString(`
170+
fragment _generated_onC2_0 on C {
171+
c1
172+
c2
173+
}
174+
175+
query Foo($flag: Boolean!) {
176+
foo {
177+
a1
178+
a2 {
179+
i
180+
... on B @include(if: $flag) {
181+
b1
182+
b2 {
183+
i
184+
..._generated_onC2_0
185+
}
186+
}
187+
}
188+
}
189+
}
190+
`);
191+
});
116192
});
117193

118194
describe('fragments optimization', () => {

internals-js/src/operations.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1658,10 +1658,10 @@ export class SelectionSet {
16581658
}
16591659

16601660
return new FragmentSpreadSelection(this.parentType, namedFragments, fragmentDefinition, []);
1661-
} else if (selection.kind === 'FieldSelection') {
1662-
if (selection.selectionSet) {
1663-
selection = selection.withUpdatedSelectionSet(selection.selectionSet.minimizeSelectionSet(namedFragments, seenSelections)[0]);
1664-
}
1661+
}
1662+
1663+
if (selection.selectionSet) {
1664+
selection = selection.withUpdatedSelectionSet(selection.selectionSet.minimizeSelectionSet(namedFragments, seenSelections)[0]);
16651665
}
16661666
return selection;
16671667
});

0 commit comments

Comments
 (0)