ardatan/graphql-mesh

OpenAPI response not getting mapped to appropriate type based on status code when the union type is renamed

charan1998 opened this issue · 10 comments

Issue workflow progress

Progress of the issue based on the
Contributor Workflow

  • 1. The issue provides a reproduction available: None

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

Please make sure Mesh 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 the output union type is renamed, mesh is not able to map the response to appropriate type based on the status code. It works fine if the types are not renamed. It works fine with rename in case of GraphQL Mesh v0.

To Reproduce Steps to reproduce the behavior:

  1. Have a OpenAPI spec that returns some response for a status code (Eg: 200) and a default response.
  2. Apply renames to the types.
  3. Compose the GraphQL schema through mesh-compose.
  4. Start a hive gateway with the generated schema.
  5. When a query/mutation is performed, mesh always tries to map the response to the default schema even when a mapping is present for the status code.

Expected behavior
The response should be mapped correctly based on the status code.

Additional context

package.json

{
  "name": "graphql-mesh-server",
  "version": "1.0.0",
  "scripts": {
    "build": "tsc",
    "format": "prettier --write \"**/*.ts\"",
    "format:check": "prettier --list-different \"**/*.ts\"",
    "lint": "eslint --max-warnings 0 --ext .ts --fix .",
    "lint:check": "eslint --max-warnings 0 --ext .ts .",
    "dev": "mesh-compose > supergraph.graphql && ts-node src/index.ts",
    "start": "mesh-compose > supergraph.graphql && node ./.build/src/index.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@envelop/prometheus": "^11.0.0",
    "@graphql-hive/gateway": "^1.3.4",
    "@graphql-mesh/compose-cli": "^1.1.4",
    "@omnigraph/openapi": "^0.107.4",
    "crypto": "^1.0.1",
    "dotenv": "^16.4.5",
    "express": "^4.21.1",
    "graphql": "^16.9.0",
    "node-fetch": "^3.3.2"
  },
  "devDependencies": {
    "@types/express": "^5.0.0",
    "@typescript-eslint/eslint-plugin": "^7.17.0",
    "@typescript-eslint/parser": "^7.17.0",
    "eslint": "^8.57.0",
    "eslint-config-prettier": "^9.1.0",
    "nodemon": "^3.1.4",
    "prettier": "^3.3.3",
    "ts-node": "^10.9.2",
    "typescript": "^5.5.4"
  },
  "engines": {
    "node": "20.12.1",
    "npm": "10.5.0"
  }
}

This is breaking after migrating to GraphQL Mesh v1. When I removed the any type renaming that is being done, it is working fine.

Could you share a reproduction or a PR with a failing test? Thanks!

Heelo @ardatan,
Here is a reproduction of the issue https://codesandbox.io/p/devbox/mystifying-haze-5fg4xz

Test Query

query MyQuery {
  feed_availability {
    ... on availability {
      in_the_news
      most_read
      on_this_day
      picture_of_the_day
      todays_featured_article
    }
    ... on problem {
      detail
      method
      status
      title
      type
      uri
    }
  }
}

Observation
On executing the query, you can see that it is trying to map the response to the default response schema. But when you comment out the rename transform, the query works as expected.

Could you share what is the expected result exactly and what you get?

@ardatan I couldn't find any issues with the schema being generated. But the issue is happening somewhere when the schema is being processed. I was able to find that it is happening when the union types are being merged using graphql tools. Basically statusCodeTypeName directive is having the correct mapping for status code to type. But when the schema is being processed, all the statusCodeTypeName directives are being overriden by default type. I couldn't exactly figure out what's going wrong.

I actually wanted to understand the differences in the result of the query. So you are getting incorrect results, no?

Got it. So, in case of the example I've specified, I'm expecting a valid response like the following.

{
  "data": {
    "feed_availability": {
      "in_the_news": [
        "test.wikipedia.org",
        "bs.wikipedia.org",
        "da.wikipedia.org",
        "de.wikipedia.org",
        "el.wikipedia.org",
        "en.wikipedia.org",
        "es.wikipedia.org",
        "fi.wikipedia.org",
        "fr.wikipedia.org",
        "he.wikipedia.org",
        "ko.wikipedia.org",
        "no.wikipedia.org",
        "pl.wikipedia.org",
        "pt.wikipedia.org",
        "ru.wikipedia.org",
        "sco.wikipedia.org",
        "sv.wikipedia.org",
        "vi.wikipedia.org"
      ],
      "most_read": [
        "*.wikipedia.org"
      ],
      "on_this_day": [
        "en.wikipedia.org",
        "de.wikipedia.org",
        "fr.wikipedia.org",
        "sv.wikipedia.org",
        "pt.wikipedia.org",
        "ru.wikipedia.org",
        "es.wikipedia.org",
        "ar.wikipedia.org",
        "bs.wikipedia.org",
        "uk.wikipedia.org",
        "it.wikipedia.org",
        "tr.wikipedia.org",
        "zh.wikipedia.org"
      ],
      "picture_of_the_day": [
        "*.wikipedia.org"
      ],
      "todays_featured_article": [
        "bg.wikipedia.org",
        "bn.wikipedia.org",
        "bs.wikipedia.org",
        "cs.wikipedia.org",
        "de.wikipedia.org",
        "el.wikipedia.org",
        "en.wikipedia.org",
        "fa.wikipedia.org",
        "he.wikipedia.org",
        "hu.wikipedia.org",
        "it.wikipedia.org",
        "ja.wikipedia.org",
        "la.wikipedia.org",
        "no.wikipedia.org",
        "sco.wikipedia.org",
        "sd.wikipedia.org",
        "sv.wikipedia.org",
        "tr.wikipedia.org",
        "ur.wikipedia.org",
        "vi.wikipedia.org",
        "zh.wikipedia.org"
      ]
    }
  }
}

But I'm getting an error as it is trying to map the response from the REST API to an incorrect type. In this case, the error type.

{
  "errors": [
    {
      "message": "Cannot return null for non-nullable field problem.type.",
      "locations": [
        {
          "line": 15,
          "column": 7
        }
      ],
      "path": [
        "feed_availability",
        "type"
      ]
    }
  ],
  "data": {
    "feed_availability": null
  }
}

#7896
Could you help me to reproduce because I couldn't here with the latest code?

Sure @ardatan. Just uncomment the lines 12 - 21 in the mesh.config.ts file of the code sandbox that I shared to reproduce the issue. I've uncommented it now. Run npm run start to start the server. You can access the GraphQL playground at /graphql path of the application.

Here is the query to run for checking the scenario.

query MyQuery {
  feed_availability {
    ... on availability {
      in_the_news
      most_read
      on_this_day
      picture_of_the_day
      todays_featured_article
    }
    ... on problem {
      detail
      method
      status
      title
      type
      uri
    }
  }
}

Hope this helps.

I cannot reproduce it with the latest versions as you can see in the PR I shared above. Could you sure you are using the latest versions, maybe help me in that PR to reproduce it?

Hello @ardatan, looks like the version was the issue. I don't remember installing any specific version. So I assumed it was the latest. I double verified it and everything is working fine now. It was my bad. Thank you so much for helping me out. I really appreciate it.

I'm closing this issue now.