Skip to content
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

Stitching returns null object when no field is offered by original object #4514

Open
4 tasks
Tracked by #5201 ...
kftsehk opened this issue Jun 7, 2022 · 0 comments
Open
4 tasks
Tracked by #5201 ...

Comments

@kftsehk
Copy link

kftsehk commented Jun 7, 2022

Issue workflow progress

Progress of the issue based on the Contributor Workflow

  • 1. The issue provides a reproduction available on Github, Stackblitz or CodeSandbox

    Make sure to fork this template and run yarn generate in the terminal.

    Please make sure the GraphQL Tools package versions under package.json matches yours.

  • 2. A failing test has been provided
  • 3. A local solution has been provided
  • 4. A pull request is pending review

Describe the bug

When making a query that original object contributes no field to selections, the resulting object is null, and no query is being made to delegate graphql server.

This case occurs when

image

To Reproduce
Steps to reproduce the behavior:

cd gateway npm i pip install awscli aws-sam-cli sam local start-api -t ./local.yml -l message.log --host 0.0.0.0 -p 3000

https://github.com/flyingmilktea/graphql-bug-reproduce/tree/no-query-at-origin-remote-null-v1

In the scenario, fields named zero* is offered by 0-th schema, named one* is offered by 1-st schema, stitched together

Query:

{
  zeroUser {
    oneValue
  }
  oneUser {
    zeroValue
  }
}
{
  "data": {
    "zeroUser": null,
    "oneUser": null
  }
}

Expected behavior

Correct result:

{
  "data": {
    "zeroUser": {
      "oneValue": "1: User: query"
    },
    "oneUser": {
      "zeroValue": "0: User: query"
    }
  }
}

Environment:

  • OS: Linux 4.18.0-372.9.1.el8.x86_64
  • "@graphql-tools/graphql-file-loader": "^7.3.14",
  • "@graphql-tools/load": "^7.5.13",
  • "@graphql-tools/schema": "^8.3.13",
  • "@graphql-tools/stitch": "^8.6.12",
  • "@graphql-yoga/node": "^2.8.0",
  • "@vendia/serverless-express": "^4.8.0",
  • NodeJS: v14.19.3

Additional context

const selections = node.selectionSet != null ? node.selectionSet.selections : null;
if (selections == null || selections.length === 0) {
return null;
}

When the original object (step 2) does not require an ID, and there is no field offered by object's original schema, all selections will be filtered out, resulting in selections.length === 0 for gateway schema.

In the case of schema stitching, it cannot be assumed that the node without selections at the gateway is safe to delete, the result of empty array is only due to the fact that all fields being offered by delegate schemas, thus has to continue onto step 4 onward to retrieve the correct result.

Here is a workaround for your reference.

if (selections == null ) {
    return null;
} else if (selections.length === 0){
    selections.push({"kind":"Field","name":{"kind":"Name","value":"__typename"},"arguments":[],"directives":[]})
}

Personally I don't consider it a fix, what it does is just adding __typename when the array is empty.
Afaik in a valid query, a non-primitive field must at least have 1 subfield selection, thus this would not happen without stitching and filtering.

E.g.:

# Invalid
{
  zeroUser {
    # type User without any subfield selected
  }
}

# Valid
{
  zeroUser {
    __typename
  }
}

Again thanks @Abbywpy for testing the issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant