You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@lutter : "The refactored code also makes a few weaknesses of the current query execution visible, in particular, field merges (from users specifying the same field multiple times, or from fragment expansion) continue to use a yolo strategy that is not entirely standard conformant. This needs to be addressed in a separate PR."
@lutter : "The refactored code also makes a few weaknesses of the current query execution visible, in particular, field merges (from users specifying the same field multiple times, or from fragment expansion) continue to use a yolo strategy that is not entirely standard conformant. This needs to be addressed in a separate PR."
I guess we can do that by adding unit tests? :)
Yes, that should be possible. The big question is what these tests check for, but this should be testable by adding to graphql/tests/query.rs. On what to test: that's why I am wondering if there are some sort of GraphQL conformance tests; for example, I beleive the query query { musicians(where: {name: "Tom" }) { id } musicians(where: {name: "Tom" }) { id } } is legal and should respond with one musicians field, but if you change Tom to Roy in the second copy of musicians, the query should result in an error. I suspect there's lots of these cases to handle.
changed the title [-]GraphQL: Ensure field merging is valid[/-][+]GraphQL: Ensure field merging is valid when merging selection-sets[/+]on Nov 30, 2021
On what to test: that's why I am wondering if there are some sort of GraphQL conformance tests; for example, I beleive the query query { musicians(where: {name: "Tom" }) { id } musicians(where: {name: "Tom" }) { id } } is legal and should respond with one musicians field, but if you change Tom to Roy in the second copy of musicians, the query should result in an error. I suspect there's lots of these cases to handle.
I checked in graphql-js and it seems like execution doesn't really care about having multiple fields, and this is done in the validate phase.
In the JS ecosystem, there is a clear distinction between the request flow phases (parse, validate, execute) and what is the role of each one, and based on the spec, there are some checks that are happening only during validate and not checked during execute.
validate phase failed on a validation rule OverlappingFieldsCanBeMergedRule (code)
execute never called because of failure.
The error I got is:
GraphQLError: Fields "a" conflict because they have differing arguments. Use different aliases on the fields to fetch both if this was intentional.
When I used the same value for b argument, the validation phase passes, so it builds an "identity" for each selection set field and then checks if it's duplicated, so arguments and aliases affect the result of this validation phase.
When I'm skipping the validate phase and go directly to execute phase, I see that the query is being executed correctly, but it does not run the additional fields (with the query above, I get {data: { a: "1" }} and the resolvers of Query.a is being called only once - so the rest of the fields are just ignored.
I guess we can take the query after it's being parsed and implement the validation rules that GraphQL spec defines, and run it before getting into the whole execution phase - this way we can find these specific issues before running any GraphQL-related code/resolver.
The GraphQL spec / graphql-js implementation has ~30 validation rules that should cover most edge cases and prevent ambiguity during execution phase. Also it also has a spec for what does a validation rule means, and how developers can extend and write their own (we are doing similar things in envelop plugins). So we can start with the defaults and then see if graphql-node needs specific validation rules.
changed the title [-]GraphQL: Ensure field merging is valid when merging selection-sets[/-][+]GraphQL: Improve documents validation before running execution flow[/+]on Nov 30, 2021
Activity
lutter commentedon Nov 29, 2021
Yes, that should be possible. The big question is what these tests check for, but this should be testable by adding to
graphql/tests/query.rs
. On what to test: that's why I am wondering if there are some sort of GraphQL conformance tests; for example, I beleive the queryquery { musicians(where: {name: "Tom" }) { id } musicians(where: {name: "Tom" }) { id } }
is legal and should respond with onemusicians
field, but if you changeTom
toRoy
in the second copy ofmusicians
, the query should result in an error. I suspect there's lots of these cases to handle.[-]GraphQL: Ensure field merging is valid[/-][+]GraphQL: Ensure field merging is valid when merging selection-sets[/+]dotansimha commentedon Nov 30, 2021
I checked in
graphql-js
and it seems like execution doesn't really care about having multiple fields, and this is done in thevalidate
phase.In the JS ecosystem, there is a clear distinction between the request flow phases (parse, validate, execute) and what is the role of each one, and based on the spec, there are some checks that are happening only during
validate
and not checked duringexecute
.I tested the following GraphQL schema:
And the following GraphQL query:
parse
phase passes because the AST is validvalidate
phase failed on a validation ruleOverlappingFieldsCanBeMergedRule
(code)execute
never called because of failure.The error I got is:
When I'm skipping the
validate
phase and go directly toexecute
phase, I see that the query is being executed correctly, but it does not run the additional fields (with the query above, I get{data: { a: "1" }}
and the resolvers ofQuery.a
is being called only once - so the rest of the fields are just ignored.@lutter I noticed that
query.rs
does onlyparse
and thenexecute
(ref) and it doesn't implement anyvalidation
phase as specified by the GraphQL spec.I guess we can take the query after it's being parsed and implement the validation rules that GraphQL spec defines, and run it before getting into the whole execution phase - this way we can find these specific issues before running any GraphQL-related code/resolver.
The GraphQL spec / graphql-js implementation has ~30 validation rules that should cover most edge cases and prevent ambiguity during execution phase. Also it also has a spec for what does a validation rule means, and how developers can extend and write their own (we are doing similar things in
envelop
plugins). So we can start with the defaults and then see ifgraphql-node
needs specific validation rules.@lutter what do you think?
[-]GraphQL: Ensure field merging is valid when merging selection-sets[/-][+]GraphQL: Improve documents validation before running execution flow[/+]validation
phase and rules #3057