Inconsistent/invalid null data response when using variables
carldunham opened this issue · comments
So we are seeing an issue with nullable fields being skipped. A query like
query($skip: Boolean = false) {
viewer @skip(if: $skip) {
login
}
}
returns (with variables {"skip": true}
)
{
"data": null
}
while
query {
viewer @skip(if: true) {
login
}
}
returns
{
"data": {}
}
Per https://spec.graphql.org/October2021/#sec-Data:
If an error was raised during the execution that prevented a valid response, the data entry in the response should be null.
but this does not seem to be an error case (or vars vs no vars would be equivalent). The spec is a bit vague about what happens if there is no error, but also nothing to return.
It also describes other error cases that would result in an errors
array, and no data
field being returned.
Not sure how all the cases would present, but certainly passing a variable shouldn't impact the ultimate return shape, I would think.
Originally posted by @carldunham in #1308 (comment)
Could you let us know what version of the Router you're using and provide the relevant portion of your schema (or an example of it) so we can consider this further?
Some additional informations here in order to resolve it later, but I think it might be related to the usage of statically_skipped
method used. Because if it's not a variable we can statically remove the selection set from the execution. That's a small optimization we have in place. We might not have same behavior between the static and non static method.
@carldunham I tried to reproduce it and I wasn't able to. Could you give me example of schema to help me reproduce it ? Also your router version please. Did you try running that query on the last release ? thank you
The example is from the github schema, but I can put together a stand-alone one for this. And we are using 1.33.2.
@bnjjj check out https://github.com/carldunham/apollo-router-4397 for a repro. In one shell
cd animal && make && make run
in another
make && make run
in a third:
curl '127.0.0.1:4000' \
-H 'accept: application/json' \
-H 'content-type: application/json' \
--data-raw '{
"query":"query ($skip: Boolean = false) { dog @skip(if: $skip) { id name } }",
"variables":{"skip":true}
}'
Let me know how that works. It uses local copies of rover
and router
to isolate things, you may want to modify it for your environment.