Repository navigation
[Fusion] Fix node lookups, hidden lookup types, client directives and pruned fields - #10683
Merged
Merged
Conversation
michaelstaib
force-pushed
the
mst/fusion-composition-gateway
branch
from
October 25, 2026 06:28
07d4f95 to
bb64009
Compare
michaelstaib
marked this pull request as ready for review
October 25, 2026 06:28
michaelstaib
force-pushed
the
mst/fusion-composition-gateway
branch
from
October 25, 2026 07:09
bb64009 to
d765e22
Compare
…l in another node lookup schema With source schema node resolution, satisfiability required every source node lookup to resolve every field of each possible type it declares. A type whose key is @external in one node lookup schema was rejected even though the planner resolves each possible type through any of its node lookups and picks the key owner. When no field of the Node interface is uniformly owned, so a query cannot bind all node branches to one source, a possible type that some node lookup fully resolves is now validated only through the node lookups that fully resolve it. An @external key field is still not served by its declaring schema and is still not key data for a transition out of it. The relaxation applies to source schema node resolution only. Gateway node resolution still validates each possible type through every by-id lookup that returns it, because the planner only tries the schemas that serve part of a node branch selection there.
…ible type Lookup completion resolved the lookup's return type through the public type view, which throws for an @inaccessible type. An Apollo Federation entity interface with an @inaccessible implementor gets a key lookup for that implementor, so the gateway could not build its schema from a composition it had accepted ("A type with the name `Private` does not exist"). The return type is now resolved like the declaring type, including inaccessible types. The planner topology cache resolved the inline fragment type conditions of lookup requirements the same way. An abstract lookup whose @is map names an inaccessible implementor (`@is(field: "<Cat>.id | <Dog>.id")` with `Dog @inaccessible`) let the gateway start and then failed the first plan, and every plan after it, with "A type with the name `Dog` does not exist". These type conditions now include inaccessible types as well.
… schema defines The merger only merged a fixed set of well-known directive definitions, and pruning removed every directive definition the schema did not apply, so an executable directive such as `directive @marker(note: String!) on FIELD` never reached the composite schema and the gateway rejected operations using it. A client directive is now merged when every source schema defines it. The merged definition keeps the shared locations among FIELD and VARIABLE_DEFINITION, the locations at which the gateway passes the directive on with the field or variable that carries it. It is repeatable only when every definition is, and keeps the arguments every definition declares with the most restrictive type and a default only when all defaults agree. The directive is left out when a source schema lacks it, when no location is shared, when argument types cannot be merged, or when a source schema requires an argument another one does not accept. Spec directives and @defer and @stream are not merged. Pruning runs on each source schema before validation, and a directive it keeps also keeps its argument types for validation and merging. Pruning therefore keeps a client directive only when every source schema defines it with a shared forwarded location, and every type its arguments reach, directly or through input object fields, has the same definition without @inaccessible elements in every source schema that defines it. Any other client directive is pruned with its argument types as before, so a client directive never makes composition fail. For example, `@format(style: Style)` with `enum Style { A B }` in one source schema and `enum Style { A B C }` in another is left out instead of failing with ENUM_VALUES_MISMATCH.
…a serves Per-source pruning removes object and interface types that a source schema cannot reach from its root types. When clients can still reach such a type in the composite schema, its fields that no other source schema resolves disappeared from the composite schema without a diagnostic. The pruning pass now returns the types it removes, and SchemaComposer records the removed object and interface types on each source schema. The new UnreachableSourceFieldRule post-merge rule reports UNREACHABLE_SOURCE_FIELD for every field of such a type when clients can reach the type in the composite schema and no other source schema contributes a non-partial declaration of the field. A field of an interface also counts as resolved when every reachable implementation resolves it. External, internal, inaccessible and overridden declarations are skipped. Client reachability is computed once per composition, and only when a removed type is part of the merged schema, by walking the merged schema from its root types through accessible fields, implemented interfaces, the implementations of interface-typed fields and union members. Types that clients cannot reach, including @inaccessible types and types reached only through @inaccessible fields, stay silently removed.
michaelstaib
force-pushed
the
mst/fusion-composition-gateway
branch
from
October 25, 2026 07:34
d765e22 to
d836a13
Compare
This was referenced Oct 25, 2026
Merged
This was referenced Oct 27, 2026
Closed
[nuget][SUI_Matcher]- Bump the sui-package-updates group with 21 updates
DFE-Digital/SUI_Matcher#424
Open
This was referenced Nov 3, 2026
Bump HotChocolate.AspNetCore.Pipeline and HotChocolate.Fusion.AspNetCore
feddi-dev/feddi-gateway#109
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Composition now accepts node lookups where a type's key is marked
@externalin another schema that has a node lookup. The gateway no longer fails to start when a lookup returns a type hidden with@inaccessible. Client directives that every source schema defines are now kept in the composite schema and sent on to the sources. Composition now fails when pruning removes a field that no other schema serves while its type is still reachable. This builds on #10682.