-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Allow interface resolveType functions to resolve to child interfaces #3599
Conversation
✅ Deploy Preview for compassionate-pike-271cb3 ready!
To edit notification comments on pull requests, go to your Netlify site settings. |
Hi @yaacovCR, I'm @github-actions bot happy to help you with this PR 👋 Supported commandsPlease post this commands in separate comments and only one per comment:
|
404f492
to
81ebe2a
Compare
hi @IvanGoncharov just checking on the status here, no rush, just curious! |
0d7cdd3
to
74d5712
Compare
2dc39ce
to
4d153df
Compare
= The child interfaces must eventually resolve to a runtime object type. = Interface cycles raise a runtime error.
good news! i rebased on main and after #3624 , the report uploads correctly! |
because it could not be the runtime type(name), could be an intermediate interface I considered just renaming it to resolvedTypeName, but that's confusing, because the variable could hold a promise, and resolvedResolvedTypeName overloads "resolve"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR still has some unfinished discussions.
But I discovered one major roadblock, it requires spec PR, because otherwise, it contradicts spec:
https://spec.graphql.org/draft/#sec-Value-Completion.Resolving-Abstract-Types
I suggest opening spec PR that changes the algorithm to be recursive.
+ I will vote for fast-track it to stage2 if you present it on the next WG.
Two things: First, what other discussions are pending?The two pending issues I had seen were the content of the error messages and whether cycles should be allowed, and I have changed this PR to correspond to your suggestions. Are you not sure of the optimal behavior with respect to one or both of these issues? Do you feel that you need a certain amount of time to think about these issues, or do these issues need feedback from the graphql-js-wg or the main graphql-wg? I will address your comment in a second, but we can work on these issues in parallel, as although async discussions have their drawback, they do allow us to open up multiple threads and make progress in parallel. Second, I think this PR does not contradict spec, as the spec says we can resolve by whatever means we want.In particular, consider the evolution of this PR. A previous version had a separate resolve method corresponding to the ResolveAbstractType step you have linked. But:
And so we had to mix the separate So, this change does not contradict the spec, but the performance (?) constraints of [Perhaps there are 3 tenets of Bottom line, I don't think we should necessarily force all complying implementations to implement this feature in JavaScript. I think it's a useful feature, but I don't know that in every language it should be mandated. However, I am fine:
Although please see above -- let's work out the other issues in the meantime. I am leaving this as open, please follow-up when possible. |
This formalizes the proprosed feature within `graphql-js` whereby the internal method provided by JavaScript for runtime type resolution is allowed to return an intermediate interface. See: Issue: graphql/graphql-js#3253 PR: graphql/graphql-js#3599 @IvanGoncharov [suggested](graphql/graphql-js#3599 (review)) that this would require a spec change. Alternatively, perhaps the recursion [should be considered to be a feature of the internal system](graphql/graphql-js#3599 (comment)) itself, possibly limited to JavaScript-like implementations. This PR provides some potential spec text, were a spec change to be considered necessary.
{ nodes: fieldNodes }, | ||
); | ||
} | ||
|
||
if (!isObjectType(runtimeType)) { | ||
if (isInterfaceType(possibleRuntimeType)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about union types?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nevermind - based on feedback from WG discussion, a union type shouldn't be possible (though does this get potentially complicated by the proposal for union constraints via implementing interfaces?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, if unions ever implement interfaces, they could potentially be a link in the chain!
throw new GraphQLError( | ||
`Abstract type "${returnType.name}" must resolve to an Object type at runtime for field "${info.parentType.name}.${info.fieldName}". Either the "${returnType.name}" type should provide a "resolveType" function or each possible type should provide an "isTypeOf" function.`, | ||
`Abstract type "${abstractType.name}" must resolve to an Object type or an intermediate Interface type at runtime for field "${info.parentType.name}.${info.fieldName}". Either the "${abstractType.name}" type should provide a "resolveType" function or each possible type should provide an "isTypeOf" function.`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about only altering this error message in the case that an intermediate Interface type actually exists as a potential case?
Looking at the unit test impact, my sense is the primary downside of this change is the additional complication to this error message that makes it slightly harder to understand.
Ideally for the large majority common case where there is no intermediate interface, we don't burden the error message
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Tailoring the error message to the interface at hand seems pretty reasonable.
Closing this, can be used as base if anyone wants to champion the associated RFC |
= The child interfaces must eventually resolve to a runtime object type.
implements: #3253