Skip to content

[Fusion] Add defer support#9506

Open
michaelstaib wants to merge 34 commits intomainfrom
mst/fusion-defer
Open

[Fusion] Add defer support#9506
michaelstaib wants to merge 34 commits intomainfrom
mst/fusion-defer

Conversation

@michaelstaib
Copy link
Copy Markdown
Member

No description provided.

Copilot AI review requested due to automatic review settings April 7, 2026 06:52
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds @defer support to the HotChocolate Fusion gateway by splitting deferred fragments during planning and streaming incremental payloads during execution.

Changes:

  • Introduces a defer-aware operation rewriter + planner path that produces DeferredExecutionGroups.
  • Adds an execution path that returns an incremental ResponseStream with pending / incremental / completed.
  • Registers @defer in the composite schema and adds planner/runtime tests + updated schema snapshots.

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Planning/DeferPlannerTests.cs New planner-level tests validating group creation, labels, nesting, and conditions.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Planning/__snapshots__/LookupTests.Require_Inaccessible_Data.graphql Snapshot updated to include @defer directive in schema output.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Execution/Types/__snapshots__/SerializeAsTests.SerializeAs_Will_Not_Be_In_The_Schema.graphql Snapshot updated to include @defer directive.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Execution/Types/__snapshots__/SerializeAsTests.SerializeAs_Will_Be_In_The_Schema.graphql Snapshot updated to include @defer directive.
src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/DeferTests.cs New end-to-end tests asserting incremental delivery payloads.
src/HotChocolate/Fusion/src/Fusion.Execution/Planning/OperationPlanner.Defer.cs New planner module to plan deferred fragments and build deferred execution nodes.
src/HotChocolate/Fusion/src/Fusion.Execution/Planning/OperationPlanner.cs Hooks defer splitting + deferred group planning into the main planning flow.
src/HotChocolate/Fusion/src/Fusion.Execution/Planning/OperationPlanner.BuildExecutionTree.cs Extends plan creation to carry deferred groups; strips @defer from subgraph operations.
src/HotChocolate/Fusion/src/Fusion.Execution/Planning/DeferOperationRewriter.cs New rewriter that extracts deferred fragments into standalone operations.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Pipeline/OperationExecutionMiddleware.cs Routes requests with deferred groups through a new executor path; blocks variable batching with @defer.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/OperationPlanExecutor.cs Implements streaming execution for deferred groups (pending/incremental/completed).
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Nodes/SelectionSet.cs Implements HasIncrementalParts for Fusion selection sets.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Nodes/Selection.cs Implements IsDeferred based on a defer mask.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Nodes/OperationPlan.cs Stores deferred groups on the operation plan.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Nodes/OperationCompiler.cs Detects presence of @defer to set HasIncrementalParts on compiled operations.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Nodes/Operation.cs Implements HasIncrementalParts.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Nodes/DeferredExecutionGroup.cs New execution model type representing one deferred fragment group.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/FusionOperationInfo.cs Broadens Reset visibility to enable cross-assembly usage.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/ExecutionState.cs Broadens AddToBacklog visibility to enable cross-assembly usage.
src/HotChocolate/Fusion/src/Fusion.Execution.Types/Completion/CompositeSchemaBuilder.cs Registers the @defer directive in the gateway schema for validation.
src/HotChocolate/Core/src/Execution.Abstractions/HotChocolate.Execution.Abstractions.csproj Adds InternalsVisibleTo for HotChocolate.Fusion.Execution.
global.json Updates SDK version pin.
dotnet-install.sh Adds .NET install helper script (vendored).
.vscode/mcp.json Updates MCP NuGet command invocation (dotnet dnx ...).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/HotChocolate/Fusion/src/Fusion.Execution/Execution/OperationPlanExecutor.cs Outdated
Comment thread src/HotChocolate/Fusion/src/Fusion.Execution/Execution/OperationPlanExecutor.cs Outdated
Comment thread src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/DeferTests.cs Outdated
Comment thread src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/DeferTests.cs Outdated
# Conflicts:
#	src/HotChocolate/Fusion/src/Fusion.Execution/Planning/OperationPlanner.BuildExecutionTree.cs
#	src/HotChocolate/Fusion/src/Fusion.Execution/Planning/OperationPlanner.cs
# Conflicts:
#	src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Execution/Types/__snapshots__/SerializeAsTests.SerializeAs_Will_Be_In_The_Schema.graphql
# Conflicts:
#	src/HotChocolate/Fusion/src/Fusion.Execution.Types/FusionSchemaOptions.cs
#	src/HotChocolate/Fusion/src/Fusion.Execution.Types/IFusionSchemaOptions.cs
#	src/HotChocolate/Fusion/src/Fusion.Execution/Execution/FusionOptions.cs
Introduces opt-in StableExecutionResultSnapshotValueFormatter and
StableGraphQLHttpResponseFormatter that aggregate incremental stream
payloads, canonicalize JSON property order, sort pending/incremental/
completed entries, and emit a merged final result. Eliminates snapshot
flakiness caused by async-ordered deferred payloads while still
surfacing protocol gaps through a diagnostics section.
- Adds JSONL support to StableGraphQLHttpResponseFormatter so it handles
  application/graphql-response+jsonl, which is what the Fusion gateway
  emits for incremental delivery.
- Adds opt-in stableStream parameter to FusionTestBase.MatchSnapshotAsync
  that buffers the HTTP body once and renders the stream through the
  stable formatter, keeping the existing OperationResult path for
  operation-plan extraction.
- Opts all DeferTests call sites into stable-stream snapshots.

The new snapshots capture pending/incremental/completed and a merged
final view that the previous OperationResult-only formatter could not
see. Existing defer snapshots will mismatch and need review; the merged
view exposes real defer behavior (including apparent path-nesting and
missing sibling dedup) that the old format was silently hiding.
The deferred plan executes against a standalone operation rooted at
Query, so its result is shaped like `{ user: { reviews: [...] } }` even
though the incremental-delivery contract requires `incremental.data` to
be the delta to merge at `pending.path`. Previously the full rooted
result was emitted as-is, causing clients to merge `user.user.reviews`
under the existing `user` object.

OperationPlanExecutor now navigates `group.Path` on the composite result
and wraps the subtree element in a path-aware IRawJsonFormatter
(DeferredPayloadDataFormatter) so the emitted data is the subtree at the
pending path, without copies and without losing nested-defer semantics.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants