apollographql / router

A configurable, high-performance routing runtime for Apollo Federation 🚀

Home Page:https://www.apollographql.com/docs/router/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.