Skip to content

[Fusion] Preserve @require-referenced external fields in Apollo Federation composition - #10064

Merged
michaelstaib merged 5 commits into
mainfrom
mst/fes-3
Jul 8, 2026
Merged

[Fusion] Preserve @require-referenced external fields in Apollo Federation composition#10064
michaelstaib merged 5 commits into
mainfrom
mst/fes-3

Conversation

@michaelstaib

Copy link
Copy Markdown
Member

No description provided.

Copilot AI review requested due to automatic review settings July 8, 2026 06:37
@michaelstaib
michaelstaib merged commit 744f9ce into main Jul 8, 2026
143 of 145 checks passed
@michaelstaib
michaelstaib deleted the mst/fes-3 branch July 8, 2026 06:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR improves Fusion’s compatibility with Apollo Federation composition and execution by (1) preserving and correctly handling requirement-related selections (including argument-safe requirement aliasing and representation shaping) and (2) tightening composition/validation behavior around federation constructs and satisfiability, with extensive new test coverage and benchmarks.

Changes:

  • Add stable internal aliases for requirement fields to prevent argument-collision merges, and plumb alias-aware mapping through plan serialization and execution result extraction.
  • Improve Apollo Federation integration: preserve federation vocab types when user-referenced, support @requires even when not explicitly defined in SDL, rewrite @requires across list intermediates, and enhance representation building for abstract composites.
  • Add/expand planner/composition/execution test coverage plus Netflix-corpus planning/parsing benchmarks.

Reviewed changes

Copilot reviewed 122 out of 123 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/HotChocolate/Mutable/src/Types.Mutable/MutableScalarTypeDefinition.cs Treat @specifiedBy URL as string and avoid throwing on non-string AST values.
src/HotChocolate/MongoDb/src/Types/ObjectIdType.cs Update scalar SpecifiedBy assignment to string.
src/HotChocolate/MongoDb/src/Types/BsonType.cs Update scalar SpecifiedBy assignment to string.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Planning/RequirementParityTests.cs Add planner regression test for non-merging requirement args.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Planning/RequirementCrossEntityTests.cs Add regression test for keeping requirement/client list fields separate when args differ.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Planning/RequirementArgumentTests.cs Add regression test for re-entrant requires argument collision scenario.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Planning/InterfaceFieldOverridePlanningTests.cs New tests pin interface-field spill behavior when ownership diverges via @override.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Planning/EntityChainTests.cs Add inline-plan assertion for nested-list key dependency ordering.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Planning/AbstractLookupFanoutPlanningTests.cs New test ensuring sibling branches remain clean with duplicate type fragments.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Planning/snapshots/RequirementParityTests.Two_Same_Service_Calls_With_Different_Requirement_Args_Do_Not_Merge.yaml New snapshot for requirement-arg non-merge behavior.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Planning/snapshots/RequirementParityTests.Two_Same_Service_Calls_With_Args_Conflicts.yaml Snapshot update reflecting internal requirement aliasing.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Planning/snapshots/RequirementCrossEntityTests.Plan_Should_Keep_Requirement_And_Client_List_Field_Separate_When_Arguments_Differ.yaml New snapshot validating argument-safe separation.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Planning/snapshots/RequirementArgumentTests.Requires_Arguments_Reentrant_Comments_Collides_With_Client_Comments.yaml New snapshot for re-entrant requires scenario.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Planning/snapshots/RequirementArgumentTests.Requires_Arguments_Deeply_Nested_Requires.yaml Snapshot update for requirement aliasing/structure.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Planning/snapshots/RequirementArgumentTests.Requires_Arguments_Deeply_Nested_Requires_With_Variables_And_Fragments.yaml Snapshot update for requirement aliasing/structure.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Planning/snapshots/RequirementArgumentTests.Requires_Arguments_Deeply_Nested_Requires_With_Variable.yaml Snapshot update for requirement aliasing/structure.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Planning/snapshots/RequirementArgumentTests.Multiple_Plain_Field_And_Requires_With_Args_That_Conflicts.yaml Snapshot update reflecting internal requirement aliasing.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Planning/snapshots/InterfaceFieldOverridePlanningTests.Plan_Should_Spill_Interface_Field_When_Concrete_Ownership_Diverges.yaml New snapshot for interface spill scenario.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Planning/snapshots/InterfaceFieldOverridePlanningTests.Plan_Should_Keep_Owning_Branch_And_Route_Only_Diverged_Branch.yaml New snapshot for mixed-ownership override routing.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Planning/snapshots/AbstractLookupFanoutPlanningTests.Plan_Should_Keep_SiblingBranch_Clean_When_Duplicate_TypeFragments_Present.yaml New snapshot for abstract lookup fanout behavior.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Execution/Results/FetchResultStoreTests.cs Add test ensuring requirement internal alias is used when reading variable value sets.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Execution/Results/FetchResultStoreRepresentationTests.cs Extend representation tests: alias-aware reads + abstract composite typename emission.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Execution/OperationPlanContextRoutingTests.cs Update test helpers for new OperationRequirement signature.
src/HotChocolate/Fusion/test/Fusion.Connectors.ApolloFederation.Tests/LookupEntityQueryRewriterTests.cs Update rewriter snapshots and representation shape builder invocation signature.
src/HotChocolate/Fusion/test/Fusion.Connectors.ApolloFederation.Compliance.Tests/Suites/RequiresWithArgument/D/PostType.cs Switch field binding to expression-based .Field(p => p.Comments).
src/HotChocolate/Fusion/test/Fusion.Connectors.ApolloFederation.Compliance.Tests/Suites/EnumIntersection/A/UserTypeType.cs Explicit enum value binding; document intentional unbound runtime value.
src/HotChocolate/Fusion/test/Fusion.Connectors.ApolloFederation.Compliance.Tests/Suites/EnumIntersection/A/UserType.cs Add runtime enum value ANONYMOUS for negative test behavior.
src/HotChocolate/Fusion/test/Fusion.Connectors.ApolloFederation.Compliance.Tests/Suites/EnumIntersection/A/AData.cs Update seed data to include ANONYMOUS and expect subgraph serialization failure.
src/HotChocolate/Fusion/test/Fusion.Connectors.ApolloFederation.Compliance.Tests/Suites/ComplexEntityCall/ComplexEntityCallTests.cs Update remarks to reflect nested-list key planning now supported.
src/HotChocolate/Fusion/test/Fusion.Connectors.ApolloFederation.Compliance.Tests/Suites/AbstractTypes/Inventory/InventorySubgraph.cs Register interface type in inventory subgraph setup.
src/HotChocolate/Fusion/test/Fusion.Connectors.ApolloFederation.Compliance.Tests/Suites/AbstractTypes/Inventory/InventoryMagazineType.cs Ensure Magazine implements the shared product interface type.
src/HotChocolate/Fusion/test/Fusion.Connectors.ApolloFederation.Compliance.Tests/Suites/AbstractTypes/Inventory/InventoryBookType.cs Ensure Book implements the shared product interface type.
src/HotChocolate/Fusion/test/Fusion.Composition.Tests/SourceSchemaParserTests.cs Add tests for federation @requires recognition vs non-federation rejection.
src/HotChocolate/Fusion/test/Fusion.Composition.Tests/SchemaComposerTests.cs Add tests for configurable invalid field deprecation severity + satisfiability default behavior.
src/HotChocolate/Fusion/test/Fusion.Composition.Tests/Satisfiability/RequirementsValidatorTests.cs Update test to new validator constructor/caching components.
src/HotChocolate/Fusion/test/Fusion.Composition.Tests/PreMergeValidationRules/SpecifiedByUrlMismatchRuleTests.cs Add test ensuring non-URI specified-by string does not crash validation rule.
src/HotChocolate/Fusion/test/Fusion.Composition.Tests/PostMergeValidationRules/RequireInvalidFieldsRuleTests.cs Add test for list-intermediate traversal in @require maps.
src/HotChocolate/Fusion/test/Fusion.Composition.Tests/MutableSchemaDefinitionExtensionsTests.cs Add fixed-point pruning tests for dead external fields after type removal.
src/HotChocolate/Fusion/test/Fusion.Composition.ApolloFederation.Tests/FederationSchemaTransformerTests.cs Add tests for preserving user-referenced FieldSet and list-syntax requires rewriting.
src/HotChocolate/Fusion/test/Fusion.Composition.ApolloFederation.Tests/snapshots/FederationSchemaTransformerTests.Transform_Should_UseListSyntax_When_RequiresPathCrossesListIntermediate.md New snapshot for list-syntax transformation output.
src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/SharedRootListTests.cs New ASP.NET Core integration test for composing shared root lists across 3 subgraphs.
src/HotChocolate/Fusion/src/Fusion.Execution/Planning/PlanNode.cs Add operation-level RequirementAliasRegistry to plan node context.
src/HotChocolate/Fusion/src/Fusion.Execution/Planning/OperationPlanner.Defer.cs Plumb requirement alias context into defer planning; use internal alias for locating requirements.
src/HotChocolate/Fusion/src/Fusion.Execution/Planning/Backlog.cs Track dependent step IDs when pushing unresolvable work.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Results/ValueCompletion.cs Support positional merging into shared list slots and surface errors on length mismatch.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Results/ResultDataMapper.cs Add internal-alias-aware path resolution when mapping requirement values.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Results/FetchResultStore.RepresentationValue.cs Emit runtime __typename for abstract, unbranched composite nodes when required.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Results/FetchResultStore.cs Read requirement values using internal alias and plumb alias through mapping fast/slow paths.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Nodes/Serialization/YamlOperationPlanFormatter.cs Serialize internalAlias for requirements in YAML format.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Nodes/Serialization/JsonOperationPlanParser.cs Parse optional internalAlias from JSON plans into OperationRequirement.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Nodes/Serialization/JsonOperationPlanFormatter.cs Emit internalAlias in JSON plan serialization and deduplicate writer logic.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Nodes/OperationRequirement.cs Extend OperationRequirement with optional InternalAlias.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Nodes/ApolloOperationExecutionNode.cs Build representation shape using schema/entity type info (new signature).
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Nodes/ApolloOperationBatchExecutionNode.cs Build representation shapes with schema/entity type info for batch lookups.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Introspection/MemHelper.cs Remove Uri overload now that SpecifiedBy is a string.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/ApolloFederation/RepresentationShapeBuilder.cs Add schema-aware shape annotation for abstract composites + internal alias response names.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/ApolloFederation/RepresentationShape.cs Add RequiresTypeName flag to shape nodes for typename emission.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/ApolloFederation/LookupEntityQueryRewriter.cs Preserve needed variable definitions when rewriting to _entities query.
src/HotChocolate/Fusion/src/Fusion.Execution.Types/PlannerTopologyCache.cs Reduce transition precomputation scope to schemas where lookups exist; remove “impossible” cache.
src/HotChocolate/Fusion/src/Fusion.Execution.Types/FusionScalarTypeDefinition.cs Change SpecifiedBy to string in Fusion execution types.
src/HotChocolate/Fusion/src/Fusion.Execution.Types/Completion/CompositeSchemaBuilder.cs Treat specified-by as string during scalar completion.
src/HotChocolate/Fusion/src/Fusion.Execution.Types/Completion/CompositeScalarTypeCompletionContext.cs Update specified-by type to string in completion context.
src/HotChocolate/Fusion/src/Fusion.Composition/SourceSchemaValidationRules/ExternalUnusedRule.cs Treat @require references as “used” for externals (in addition to @provides).
src/HotChocolate/Fusion/src/Fusion.Composition/SourceSchemaPreprocessor.cs Defer external stripping until after schema validation; plumb invalid deprecation severity.
src/HotChocolate/Fusion/src/Fusion.Composition/SourceSchemaParser.cs Register federation @requires directive for federation source texts before parsing.
src/HotChocolate/Fusion/src/Fusion.Composition/SchemaComposer.cs Thread per-source invalid field deprecation severity into parsing/preprocessing.
src/HotChocolate/Fusion/src/Fusion.Composition/SatisfiabilityValidator.cs Add caches for lookups/transitions and share them through requirements validation.
src/HotChocolate/Fusion/src/Fusion.Composition/Satisfiability/SourceSchemaTransitionHelper.cs Add transition memoization and cycle-collision scoping to direct lookup validation.
src/HotChocolate/Fusion/src/Fusion.Composition/Satisfiability/SourceSchemaTransitionCache.cs New per-run cache for direct transition satisfiability and associated errors.
src/HotChocolate/Fusion/src/Fusion.Composition/Satisfiability/RequirementsValidator.cs Accept caches and reuse them across recursive validations.
src/HotChocolate/Fusion/src/Fusion.Composition/Satisfiability/FusionLookupDirectiveCache.cs New cache for possible @fusion__lookup directives (including unions) and by-id filtering.
src/HotChocolate/Fusion/src/Fusion.Composition/Properties/CompositionResources.resx Add resource strings for federation @requires directive definition.
src/HotChocolate/Fusion/src/Fusion.Composition/Properties/CompositionResources.Designer.cs Add generated accessors for new @requires resource strings.
src/HotChocolate/Fusion/src/Fusion.Composition/PreMergeValidationRules/SpecifiedByUrlMismatchRule.cs Compare specified-by values as raw strings.
src/HotChocolate/Fusion/src/Fusion.Composition/Options/SourceSchemaOptions.cs Add option to configure invalid field deprecation severity per source schema.
src/HotChocolate/Fusion/src/Fusion.Composition/Extensions/MutableSchemaDefinitionExtensions.cs Factor lookup directive selection core + add fixed-point pruning of dead externals.
src/HotChocolate/Fusion/src/Fusion.Composition/Extensions/CompositionLogExtensions.cs Allow mapping invalid field deprecation validation finding to configurable severity.
src/HotChocolate/Fusion/src/Fusion.Composition/Definitions/RequiresMutableDirectiveDefinition.cs New mutable directive definition to bind federation @requires during parsing.
src/HotChocolate/Fusion/src/Fusion.Composition/Collections/SatisfiabilityPath.cs Track collision depth for cycle handling and memoization safety.
src/HotChocolate/Fusion/src/Fusion.Composition/ApolloFederation/TransformRequiresToRequire.cs Generate nullable require args; support list-intermediate paths via list-syntax maps + nested inputs.
src/HotChocolate/Fusion/src/Fusion.Composition/ApolloFederation/RemoveFederationInfrastructure.cs Preserve federation vocab types when referenced by user-defined schema members.
src/HotChocolate/Fusion/src/Fusion.Composition/ApolloFederation/RemoveExternalFields.cs Preserve externals referenced by @provides and @require; add dead-external fixed-point removal.
src/HotChocolate/Fusion/benchmarks/Fusion.Execution.Benchmarks/VariableMergingBenchmark.cs Update benchmark helper for OperationRequirement signature.
src/HotChocolate/Fusion/benchmarks/Fusion.Execution.Benchmarks/Program.cs Add probe entrypoint for Netflix feasibility probe.
src/HotChocolate/Fusion/benchmarks/Fusion.Execution.Benchmarks/NetflixPlanningProbe.cs New one-shot Netflix corpus feasibility probe with bounded schema build.
src/HotChocolate/Fusion/benchmarks/Fusion.Execution.Benchmarks/NetflixPlanningBenchmark.cs New BenchmarkDotNet planning benchmarks for Netflix corpus.
src/HotChocolate/Fusion/benchmarks/Fusion.Execution.Benchmarks/NetflixParsingBenchmark.cs New BenchmarkDotNet parsing benchmarks for Netflix corpus.
src/HotChocolate/Fusion/benchmarks/Fusion.Execution.Benchmarks/NetflixCorpusPaths.cs New corpus path resolver for Netflix benchmarks (env/ancestor discovery).
src/HotChocolate/Core/src/Types/Types/Scalars/UuidType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types/Types/Scalars/UrlType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types/Types/Scalars/UriType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types/Types/Scalars/UnsignedShortType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types/Types/Scalars/UnsignedLongType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types/Types/Scalars/UnsignedIntType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types/Types/Scalars/UnsignedByteType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types/Types/Scalars/ShortType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types/Types/Scalars/ScalarType.cs Change ScalarType.SpecifiedBy from Uri? to string?.
src/HotChocolate/Core/src/Types/Types/Scalars/LongType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types/Types/Scalars/LocalTimeType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types/Types/Scalars/LocalDateType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types/Types/Scalars/LocalDateTimeType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types/Types/Scalars/DurationType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types/Types/Scalars/DecimalType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types/Types/Scalars/DateType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types/Types/Scalars/DateTimeType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types/Types/Scalars/ByteType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types/Types/Scalars/Base64StringType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types/Types/Scalars/AnyType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types/Types/Introspection/__Type.cs Return specified-by as string in introspection field.
src/HotChocolate/Core/src/Types/Types/Factories/SchemaFirstTypeInterceptor.cs Store specified-by URL as string during schema-first interception.
src/HotChocolate/Core/src/Types/Types/Descriptors/Configurations/ScalarTypeConfiguration.cs Change configuration property to string? SpecifiedBy.
src/HotChocolate/Core/src/Types.Validation/HotChocolate.Types.Validation.csproj Add InternalsVisibleTo for Fusion composition access.
src/HotChocolate/Core/src/Types.NodaTime/LocalTimeType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types.NodaTime/LocalDateType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types.NodaTime/LocalDateTimeType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types.NodaTime/DurationType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types.NodaTime/DateTimeType.cs Update scalar specified-by assignment to string.
src/HotChocolate/Core/src/Types.Abstractions/Types/IScalarTypeDefinition.cs Change SpecifiedBy contract to string?.
src/HotChocolate/Core/src/Types.Abstractions/Types/Extensions/HotChocolateTypesAbstractionsScalarDefinitionExtensions.cs Update specified-by lookup to use string value.
src/HotChocolate/Core/src/Types.Abstractions/Serialization/SchemaFormatter.cs Emit @specifiedBy(url: ...) using string value.
src/HotChocolate/Adapters/src/Adapters.OpenApi.AspNetCore/DynamicOpenApiDocumentTransformer.cs Update OpenAPI scalar-format inference to use string SpecifiedBy.
src/HotChocolate/Adapters/src/Adapters.Mcp.Core/Extensions/TypeExtensions.cs Update JSON schema inference helpers to use string SpecifiedBy.
Files not reviewed (1)
  • src/HotChocolate/Fusion/src/Fusion.Composition/Properties/CompositionResources.Designer.cs: Generated file

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

Comment on lines +335 to +359
// A @require map that traverses an object- or interface-typed
// intermediate (a nested selection such as
// "dimensions { size weight }") keeps its ENTIRE subtree with
// @external intact: the intermediate path field has to stay
// traversable and its leaf fields belong to the same non-resolvable
// input contribution, so dropping them would leave the intermediate
// type empty. A map that is a flat, root-level scalar requirement
// (such as "price") keeps nothing: its external leaf is removed so it
// never competes with its real owner as a spurious partial
// contribution.
var hasComplexIntermediate = false;

foreach (var selectedField in selectedFields)
{
if (selectedField.Type.NamedType() is IComplexTypeDefinition)
{
hasComplexIntermediate = true;
break;
}
}

if (!hasComplexIntermediate)
{
continue;
}
using System;
using System.IO;

namespace HotChocolate.Fusion.Benchmarks;
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.

2 participants