-
Notifications
You must be signed in to change notification settings - Fork 1.1k
[RFC] Introduce Strict and Legacy All Variable Usages Are Allowed #1059
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
base: main
Are you sure you want to change the base?
Conversation
✅ Deploy Preview for graphql-spec-draft ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
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 is well thought out!
which would become invalid under the Strict Algorithm, in which case you should | ||
implement the Legacy Algorithm. |
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.
"In which case you must implement the Legacy Algorithm until the existing documents are migrated to satisfy the strict algorithm"
Implement this only if you are not implementing | ||
[Legacy All Variable Usages Are Allowed](#sec-Legacy-All-Variable-Usages-Are-Allowed). |
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.
I'm not sure "Implement this only if" is what we want. If you implement legacy then we also want you implementing strict.
Maybe we should have validation warnings? Where if you implement both:
- if strict validation succeeds, no error
- if legacy validation succeeds, warn
- if legacy validation fails, fail.
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.
Implementing both would be redundant, wouldn’t it? But yeah, this shouldn’t be a strict rule, probably a “we recommend you implement this only if” instead, from an efficiency POV.
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.
(I like the warn idea.)
TODO: if this is merged after oneOf (which it surely will be), add this counter-example (removed in mutation addNullableCatWithDefault($cat: CatInput = { name: "Brontie" }) {
addPet(pet: { cat: $cat }) {
name
}
} Thanks to @glen-84 for pointing out the issue. |
* Renumber list items * @OneOf input objects * @OneOf fields * Fix typos (thanks @eapache!) * Much stricter validation for oneof literals (with examples) * Add missing coercion rule * Clearer wording of oneof coercion rule * Add more examples for clarity * Rename introspection fields to oneOf * Oneof's now require exactly one field/argument, and non-nullable variables. * Remove extraneous newline * graphgl -> graphql * Apply suggestions from @eapache's review * Apply suggestions from code review Co-authored-by: Michael Staib <[email protected]> * Update spec/Section 3 -- Type System.md * Remove Oneof Fields from spec * Oneof -> OneOf * Spellings * Remove out of date example * Rename __Type.oneOf to __Type.isOneOf * Add a:null example * Rewrite to avoid ambiguity of language * Forbid 'extend input' from introducing the @OneOf directive * Add yet more examples to the example coercion table * Indicate `@oneOf` is a built-in directive Co-authored-by: Shane Krueger <[email protected]> * Update spec/Section 3 -- Type System.md * remove OneOf-specific rule in favor of update to VariablesInAllowedPositions for simplicity, this PR retains the same problems for variables with defaults that are fixed by strict All Variable Usages Are Allowed * Clarify IsNonNullPosition algorithm * Clarify OneOf examples * Add more examples * Null literal is separate * Use 'execution error' and 'raise' rather than throw an error * Update spec/Section 3 -- Type System.md * Whitespace Co-authored-by: Glen <[email protected]> * Clarify algorithm * Rename 'Tagged' * editorial: define and link _OneOf Input Object_ * execution error -> request error (input coercion) * Simplify and clarify OneOf Input Object additional coercion rules * Clarity and correctness * Simplify * Use a colon * Use the correct error for the situation * Remove example which will not always fail until #1059 is adopted * copy tweaks and remove redundant examples * dedicated subsection * rogue plural + links * sp * sp --------- Co-authored-by: Michael Staib <[email protected]> Co-authored-by: Shane Krueger <[email protected]> Co-authored-by: Yaacov Rydzinski <[email protected]> Co-authored-by: Glen <[email protected]> Co-authored-by: Lee Byron <[email protected]>
For the following schema:
The following query is currently valid:
This query will accept the variables
{"number": null}
and result in a runtime field error when it turns out thatnull
cannot be used in this non-nullable list value position. This was discussed in depth in the December 2022 Secondary EU WG meeting, resulting in this action item graphql/graphql-wg#1337. Timestamped link to the relevant part of the discussion: https://youtu.be/nkPn-F_UBJo?list=PLP1igyLx8foH30_sDnEZnxV_8pYW3SDtb&t=2702This PR implements the agreed solution: it introduces a stricter version of the All Variable Usages Are Allowed algorithm which forbids a nullable variable from being used in a non-nullable position; and to support existing documents a legacy version of the old algorithm is maintained (basically a copy/paste).
Under the new strict algorithm, the previous query becomes invalid and you'd need to make the variable type non-nullable:
This still allows the variable
$number
to be omitted, but it does not allow it to be explicitlynull
.IMPORTANT NOTE: this new algorithm does not allow an argument/input object field's default value to be used if a variable is used as the value for that argument/input object field. A workaround is to copy the argument/input object field's default value to the variable definition, but this will mean that changes to the argument/input object field's default value will not be reflected by existing queries. I think this is acceptable, since there's no way to leverage the default value of an argument when passing a literal to it either - I'm in favour of literal/variable equivalence where possible, and I think that the benefits of turning this runtime error into a validation error outweigh the costs.
cc @leebyron @mjmahone @IvanGoncharov as they were participants in the discussion above and contributed to this decision.