-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
[RFC] Non-existent request field operator #1014
Comments
This is a really interesting idea, and may help with adding things to the introspection schema too. Currently we have to do two or more introspection queries, the first determining what the server supports and the second then being built based on this. I imagine a Are you looking to be champion of this proposal? If so, you should add yourself and the topic to an upcoming WG agenda: |
+1. I've bumped into this issue recently as well and was considering modifying the document at runtime based on some directives: type Query {
v1Field: String @since(version: 1)
v2Field: String @since(version: 2)
} If talking to a v1 server, a client could decide to strip the
So having a simple |
Not to open a can of worms here, but is this need specific to fields, or to other things as well (type names in inline fragments, argument names, directives...)? |
Would the semantics here be that, if the field does not exist, validation (and execution) treat the field as if it were absent from the AST? Does that include ignoring its arguments and everything inside its selection set recursively (even, eg, directives applied inside its selection set that may or may not be defined) for the sake of validation? (Though not for all validation rules: eg, if a variable is only used in an argument to an |
@benjie I can be the champion after the end of my current affiliation weeks later, otherwise there is an obligatory, usually lengthy process to get through in order to sign the CLA. Please do not mark this rejected due to the lack of a champion for now. |
@SuibianP No rush! |
I believe it should be applicable for anything that can result in a component in the response -- which inline fragments as a whole and the fields within it definitely are. For argument names and directives, I am not so sure, partly because one cannot tell the existence of such token from the response in the lack of a sentinel value.
Yes, anything marked so is essentially purged from the AST, except for the validation rules you mentioned. Also, what should happen if all fields are non-existent, resulting in an empty object? |
We already allow empty objects; both of the following queries could return query EmptyObject1 {
me {
__typename @skip(if: true)
}
}
query EmptyObject2 {
me { # `type User implements Node`
... on Node {
... on Post {
id
}
}
}
} |
As it currently stands, the “breaking change” GraphQL best practice is largely based upon the assumption that server schemas are never older than client schemas, which is not the case for self-hosted instances of server software that are not centrally managed.
For example, GitHub client applications may desire to query the newly added
hasVulnerabilityAlertsEnabled
field on theRepository
type to provide additional information to the user if available. However, adding this field to the query is sure to break the compatibility with servers on earlier schema versions, such as GitHub Enterprise users.This effectively leaves the same problem as traditional REST APIs — every change can be seen as breaking. To ensure both backward and forward compatibility, the client has to resort to either separate queries or API versioning. Both of the workarounds are against the design rationale of GraphQL and quickly become unmanageable with the rolling schema iteration encouraged by GraphQL design.
There should be a way to specify that a field in the query may be non-existent, or “I hope your server have some clue about this field but do not panic if not and just give me whatever you have now“. The need is not satisfied with nullable fields or error policies because it is a validation error instead of a resolver one.
If null is to be used as the sentinel response value of non-existent field, this operator shall imply non-null.
The text was updated successfully, but these errors were encountered: