-
Notifications
You must be signed in to change notification settings - Fork 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
graph, graphql: introduce GraphQL spec-compliant validation
phase and rules
#3057
Conversation
validation
phasevalidation
phase
9561a2d
to
18e8620
Compare
validation
phasevalidation
phase
validation
phasevalidation
phase and rules
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.
Nice progress! Two things:
- With this approach, each validation requires a pass over the AST; probably not a big deal right now, but something to keep in mind as the number of validations grows.
- It should be possible to turn all validations off with an environment variable - that's just so that when we roll this out in the hosted service, we can turn it off in case it breaks users' queries to give them some time to fix their queries. In the long run, that env variable will go away, but it's good to have that as we introduce new behavior.
Also, would it be possible to add a validation for this We actually have a bug right now where we run queries that violate this sentence:
If selectionType is an interface, union, or object
The subselection set of that selection must NOT BE empty
Thank you for the review @lutter !
I agree, that's why I also created this issue: #3077 . We can start with that and then add caching.
Sure, a flag like
Sure (issue: dotansimha/graphql-tools-rs#3), I'll work on that now. |
c055457
to
fb8352a
Compare
Ok so now we have more rules :) The
Also, added an env var to skip the new validations. And moved it to the I think we are just waiting for dotansimha/graphql-tools-rs#4 and we can continue with this one. I believe at some point, we can remove the complexity checks and |
6a7e299
to
b226303
Compare
@lutter I updated to latest |
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 looks great now! I really like how explicit the error messages are.
One small change to move the validation plan out of the runner, and this is good to merge. That change will get rid of a bunch of small modifications to pass the plan around.
Also, before merging, can you squash this? The PR now has a lot of small commits that reflect more this discussion than the sequence of steps needed to get to this point which in the long term don't make that much sense.
As for removing validate_fields
: yes, I think we can remove this now. I would like to first roll this PR out so that if we have to disable the validations, we still have whatever validate_fields
does right now, and then follow it with a PR in a week or so that gets rid of the env var to turn validations off and removes validate_fields
.
d8d6003
to
c37e38a
Compare
❤️
Done! it's now
Squashed ✅
I added |
4b12a06
to
ba6ff53
Compare
72da9d3
to
d920429
Compare
I just approved this, but then noticed that there are changes to tests that I don't understand why they are necessary. It would be good to remove those changes before merging. Also, the commit message right now is just a log of squashed commits and is not very helpful. It should be changed to something like:
|
ba7f141
to
e48af76
Compare
Sure. Please see my comments above - I explained on each test what's the reason for changing it.
✅ Also, I rebased and now it seems like I'm getting some build errors (I guess coming from |
0f547b9
to
3558833
Compare
validation
phase and rulesvalidation
phase and rules
3558833
to
7b32240
Compare
Uses `graphql-tools-rs` for the actual validation. Validation can be turned off by setting `DISABLE_GRAPHQL_VALIDATIONS=true` in the environment.
7b32240
to
ccb3516
Compare
Background
While @lutter worked on a refactor for the GraphQL execution (#3005), we needed a way to make sure some aspects of execution are valid after merging the refactor PR.
We also noticed that the current implementation of the GraphQL engine does not include a validation phase (#3013).
This PR uses
graphq-tools
crate (https://github.com/dotansimha/graphql-tools-rs, a set of utils on top ofgraphql_parser
crate) for validations, using visitor pattern (similar to GraphQL-JS ecosystem).The following rules are now running:
UniqueOperationNames
(https://spec.graphql.org/draft/#sec-Operation-Name-Uniqueness)SingleFieldSubscriptions
(https://spec.graphql.org/draft/#sec-Operation-Name-Uniqueness)KnownTypeNames
(https://spec.graphql.org/draft/#sec-Fragment-Spread-Type-Existence)VariablesAreInputTypes
(https://spec.graphql.org/draft/#sec-Variables-Are-Input-Types)FieldsOnCorrectType
(https://spec.graphql.org/draft/#sec-Field-Selections)LoneAnonymousOperation
(https://spec.graphql.org/draft/#sec-Lone-Anonymous-Operation)FragmentsOnCompositeTypes
(https://spec.graphql.org/draft/#sec-Fragments-On-Composite-Types)OverlappingFieldsCanBeMerged
(https://spec.graphql.org/draft/#sec-Field-Selection-Merging)NoUnusedFragments
(https://spec.graphql.org/draft/#sec-Fragments-Must-Be-Used)KnownFragmentNamesRule
(https://spec.graphql.org/draft/#sec-Fragment-spread-target-defined)LeafFieldSelections
(https://spec.graphql.org/draft/#sec-Leaf-Field-Selections)UniqueFragmentNames
(https://spec.graphql.org/draft/#sec-Fragment-Name-Uniqueness)NoFragmentsCycle
(https://spec.graphql.org/draft/#sec-Fragment-spreads-must-not-form-cycles)PossibleFragmentSpreads
(https://spec.graphql.org/draft/#sec-Fragment-spread-is-possible)NoUnusedVariables
(https://spec.graphql.org/draft/#sec-All-Variables-Used)NoUndefinedVariables
(https://spec.graphql.org/draft/#sec-All-Variable-Uses-Defined)KnownArgumentNames
(https://spec.graphql.org/draft/#sec-Argument-Names , https://spec.graphql.org/draft/#sec-Directives-Are-In-Valid-Locations)UniqueArgumentNames
(https://spec.graphql.org/draft/#sec-Argument-Names)UniqueVariableNames
(https://spec.graphql.org/draft/#sec-Variable-Uniqueness)ProvidedRequiredArguments
(https://spec.graphql.org/draft/#sec-Required-Arguments)The following spec rules are not part of this PR:
ExecutableDefinitions
(not actually needed, because ofgraphql_parser
nature)ValuesOfCorrectType
(WIP - not sure yet about requirement bygraph-node
)VariablesInAllowedPosition
(WIP - might be needed bygraph-node
)UniqueInputFieldNames
(blocked by Avoid using BTreeMap inValue::Object
and useVec<(String, Value::Object)
instead? graphql-rust/graphql-parser#59)KnownDirectives
- not needed at the moment bygraph-node
.UniqueDirectivesPerLocation
- not needed at the moment bygraph-node
.Changes in the PR
A
ValidationPlan
struct is now constructed in a static way, including all the rules, and can be disabled using the env varDISABLE_GRAPHQL_VALIDATIONS=true
.If there are any validation rules selected, the query fails with a standard error, based on the GraphQL spec:
Future tasks
ValidationRule
and use it there, it should make the GraphQL layer a bit more generic.validate_fields
since it's covered by new validations.TODO
validate
flow based on the specgraphql_parser
Document
OverlappingFieldsCanBeMerged
OverlappingFieldsCanBeMerged
implementation