Skip to content

Commit

Permalink
fix: fix recursion logic in minimizeSelectionSet (#3158)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
dariuszkuc authored Sep 30, 2024
1 parent ad94371 commit df5eb3c
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/violet-cows-talk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@apollo/federation-internals": patch
---

Fix fragment generation recursion logic to apply minification on all subselections.
78 changes: 77 additions & 1 deletion internals-js/src/__tests__/operations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ describe('generate query fragments', () => {
);

const withGeneratedFragments = operation.generateQueryFragments();
console.log(withGeneratedFragments.toString());
expect(withGeneratedFragments.toString()).toMatchString(`
fragment _generated_onB1_0 on B {
... on B {
Expand All @@ -113,6 +112,83 @@ describe('generate query fragments', () => {
}
`);
});

test('minimizes all sub selections', () => {
const schema = parseSchema(`
type Query {
foo: A
}
type A {
a1: Int
a2: I
}
interface I {
i: Int
}
type B implements I {
i: Int
b1: String
b2: I
}
type C implements I {
i: Int
c1: Int
c2: String
}
`);

const operation = parseOperation(
schema,
`
query Foo($flag: Boolean!) {
foo {
a1
a2 {
i
... on B @include(if: $flag) {
b1
b2 {
i
... on C {
c1
c2
}
}
}
}
}
}
`,
);

const withGeneratedFragments = operation.generateQueryFragments();
expect(withGeneratedFragments.toString()).toMatchString(`
fragment _generated_onC2_0 on C {
c1
c2
}
query Foo($flag: Boolean!) {
foo {
a1
a2 {
i
... on B @include(if: $flag) {
b1
b2 {
i
..._generated_onC2_0
}
}
}
}
}
`);
});
});

describe('fragments optimization', () => {
Expand Down
8 changes: 4 additions & 4 deletions internals-js/src/operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1658,10 +1658,10 @@ export class SelectionSet {
}

return new FragmentSpreadSelection(this.parentType, namedFragments, fragmentDefinition, []);
} else if (selection.kind === 'FieldSelection') {
if (selection.selectionSet) {
selection = selection.withUpdatedSelectionSet(selection.selectionSet.minimizeSelectionSet(namedFragments, seenSelections)[0]);
}
}

if (selection.selectionSet) {
selection = selection.withUpdatedSelectionSet(selection.selectionSet.minimizeSelectionSet(namedFragments, seenSelections)[0]);
}
return selection;
});
Expand Down

0 comments on commit df5eb3c

Please sign in to comment.