-
-
Notifications
You must be signed in to change notification settings - Fork 816
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inline fragments are only evaluated against the first subschema containing the merge type #4966
Comments
Hi 👋, we have experienced a similar issue with stitching... Please see a replication of this issue here https://github.com/metallicOxide/type-merging-interfaces We discovered that with the type merging approach described here the We were able to get around this issue by using schema-extensions instead however this is not ideal as we had to create stub types which we extended. The approach is described here -> https://the-guild.dev/graphql/stitching/docs/approaches/schema-extensions#basic-example |
One possible workaround is to avoid merging union/interface types between two schemas, and instead add the fields that refer to them to the stitched schema, along with a resolver that delegates to the appropriate subschema. Something like this: let studentSchema = makeExecutableSchema({
typeDefs: /* GraphQL */ `
type Query {
student(id: String!): Student
}
type Student {
id: String!
name: String!
# major: Major ## Add this later, in stitching
}
`,
});
let majorsSchema = makeExecutableSchema({
typeDefs: /* GraphQL */ `
type Query {
major(id: String!): Major @merge(keyField: "id")
}
union Major = MajorError | MajorSuccess # Allow for different return values
type MajorError {
id: String!
code: String!
}
type MajorSuccess {
id: String!
name: String!
}
`,
});
stitchSchemas({
subschemas: [studentSchema, majorsSchema],
typeDefs: `extend type Student { major: Major}`,
resolvers: {
Student: {
major: {
selectionSet: forwardArgsToSelectionSet('{ id }'),
resolve: (
selections: { id: string },
args,
context,
info,
) => delegateToSchema({
schema: majorsSchema,
operation: OperationTypeNode.QUERY,
fieldName: 'major',
args: {
id: selections.id,
},
context,
info,
}),
},
},
},
}); |
One of the things that also worked for me was making a direct call to
Strange enough, passing in the 5th argument in resolve ( |
Issue workflow progress
Progress of the issue based on the Contributor Workflow
Describe the bug
See unit tests in PR #4965
When we provide the query
to the stitched schema, it first executes the Student type against the student subschema. The major type that is returned only contains an ID. The presence of a major ID on its own doesn't give us enough information to pick an inline fragment to evaluate. My understanding is that selecting a fragment is the work of either 1) a provided __typename, an __isTypeOf resolver, or the __resolveType resolver. Regardless of which strategy is used, the type is compared to the inline fragments after the student schema returns its response. The student schema does not have enough information to determine whether the major schema will decide that the type is a MajorSuccess or a MajorError. As such, GraphQL fails to match an inline fragment and determines that the major field is completed. Since the major field is completed, no request to the major schema is made.
To Reproduce
Steps to reproduce the behavior:
See unit tests in PR #4965
Expected behavior
I think I expect the selection set containing the inline fragments to be evaluated by subsequent subgraphs containing merge type definitions for the union type. Although I understand that this might not be supported or that I might be missing a configuration option that enables this behavior.
Environment:
@graphql-tools/...
:Additional context
The text was updated successfully, but these errors were encountered: