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

Cannot convert swagger (oas2.0) to graphql #354

Open
pharindoko opened this issue Jan 19, 2021 · 1 comment
Open

Cannot convert swagger (oas2.0) to graphql #354

pharindoko opened this issue Jan 19, 2021 · 1 comment

Comments

@pharindoko
Copy link

Describe the bug
When I use the library with following code

  const { schema, report } = await createGraphQLSchema(this.swaggerSpec);

I do get an error

[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "Could not convert Swagger 'json-serverless-lib' to OpenAPI Specification. YAML anchor or merge key at #/paths/~1api~1posts/post/responses/201/schema".] {

This works fine in swagger.io editor (no error)
https://editor.swagger.io/

To Reproduce
this is the sample swagger spec.
Steps to reproduce the behavior:

{
  "basePath": "/",
  "info": {
    "version": "1.6.15",
    "title": "json-serverless-lib",
    "license": { "name": "MIT" },
    "description": "[Specification JSON](//api-spec)\n\nTransform a json file into an api"
  },
  "paths": {
    "/api/posts": {
      "get": {
        "summary": "/api/posts",
        "consumes": ["application/json"],
        "parameters": [
          {
            "name": "_page",
            "in": "query",
            "required": false,
            "type": "integer",
            "description": "parameter to return paginated data"
          },
          {
            "name": "_limit",
            "in": "query",
            "required": false,
            "type": "integer",
            "description": "parameter to limit paginated data"
          },
          {
            "name": "_sort",
            "in": "query",
            "required": false,
            "type": "string",
            "description": "sort by attributes"
          },
          {
            "name": "_order",
            "in": "query",
            "required": false,
            "type": "string",
            "description": "order ascending or descending",
            "enum": ["asc", "desc"]
          },
          {
            "name": "_start",
            "in": "query",
            "required": false,
            "type": "integer",
            "description": "parameter to set start sliced data"
          },
          {
            "name": "_end",
            "in": "query",
            "required": false,
            "type": "integer",
            "description": "parameter to set start sliced data"
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "type": "string",
            "description": "full text search"
          },
          {
            "name": "_embed",
            "in": "query",
            "required": false,
            "type": "string",
            "description": "include children resources"
          },
          {
            "name": "_expand",
            "in": "query",
            "required": false,
            "type": "string",
            "description": "include parent resource"
          }
        ],
        "responses": {
          "200": {
            "schema": { "$ref": "#/definitions/posts" },
            "description": "successful operation"
          }
        },
        "produces": ["application/json"],
        "tags": ["posts"]
      },
      "post": {
        "summary": "/api/posts",
        "consumes": ["application/json"],
        "parameters": [
          {
            "schema": { "$ref": "#/definitions/posts/items" },
            "in": "body",
            "name": "body",
            "description": "posts",
            "required": true
          }
        ],
        "responses": {
          "201": {
            "description": "successful operation",
            "schema": { "$ref": "#/definitions/posts/items" }
          },
          "400": { "description": "invalid posts" }
        },
        "produces": ["application/json"],
        "tags": ["posts"]
      }
    },
    "/api/posts/{id}": {
      "get": {
        "summary": "/api/posts/{id}",
        "consumes": ["application/json"],
        "parameters": [
          { "name": "id", "in": "path", "required": true, "type": "integer" }
        ],
        "responses": {
          "200": {
            "schema": { "$ref": "#/definitions/posts/items" },
            "description": "successful operation"
          }
        },
        "produces": ["application/json"],
        "tags": ["posts"]
      },
      "put": {
        "summary": "/api/posts/{id}",
        "consumes": ["application/json"],
        "parameters": [
          { "name": "id", "in": "path", "required": true, "type": "integer" },
          {
            "schema": { "$ref": "#/definitions/posts/items" },
            "in": "body",
            "name": "body",
            "description": "posts",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "successful operation",
            "schema": { "$ref": "#/definitions/posts/items" }
          },
          "400": { "description": "invalid ID supplied" },
          "404": { "description": "posts not found" },
          "405": { "description": "Validation exception" }
        },
        "produces": ["application/json"],
        "tags": ["posts"]
      },
      "patch": {
        "summary": "/api/posts/{id}",
        "consumes": ["application/json"],
        "parameters": [
          { "name": "id", "in": "path", "required": true, "type": "integer" },
          {
            "schema": { "$ref": "#/definitions/posts/items" },
            "in": "body",
            "name": "body",
            "description": "posts",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "successful operation",
            "schema": { "$ref": "#/definitions/posts/items" }
          },
          "400": { "description": "invalid ID supplied" },
          "404": { "description": "posts not found" },
          "405": { "description": "Validation exception" }
        },
        "produces": ["application/json"],
        "tags": ["posts"]
      },
      "delete": {
        "summary": "/api/posts/{id}",
        "consumes": ["application/json"],
        "parameters": [
          { "name": "id", "in": "path", "required": true, "type": "integer" }
        ],
        "responses": {
          "200": { "description": "successful operation" },
          "400": { "description": "invalid ID supplied" },
          "404": { "description": "posts not found" }
        },
        "produces": ["application/json"],
        "tags": ["posts"]
      }
    },
    "/api/comments": {
      "get": {
        "summary": "/api/comments",
        "consumes": ["application/json"],
        "parameters": [
          {
            "name": "_page",
            "in": "query",
            "required": false,
            "type": "integer",
            "description": "parameter to return paginated data"
          },
          {
            "name": "_limit",
            "in": "query",
            "required": false,
            "type": "integer",
            "description": "parameter to limit paginated data"
          },
          {
            "name": "_sort",
            "in": "query",
            "required": false,
            "type": "string",
            "description": "sort by attributes"
          },
          {
            "name": "_order",
            "in": "query",
            "required": false,
            "type": "string",
            "description": "order ascending or descending",
            "enum": ["asc", "desc"]
          },
          {
            "name": "_start",
            "in": "query",
            "required": false,
            "type": "integer",
            "description": "parameter to set start sliced data"
          },
          {
            "name": "_end",
            "in": "query",
            "required": false,
            "type": "integer",
            "description": "parameter to set start sliced data"
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "type": "string",
            "description": "full text search"
          },
          {
            "name": "_embed",
            "in": "query",
            "required": false,
            "type": "string",
            "description": "include children resources"
          },
          {
            "name": "_expand",
            "in": "query",
            "required": false,
            "type": "string",
            "description": "include parent resource"
          }
        ],
        "responses": {
          "200": {
            "schema": { "$ref": "#/definitions/comments" },
            "description": "successful operation"
          }
        },
        "produces": ["application/json"],
        "tags": ["comments"]
      },
      "post": {
        "summary": "/api/comments",
        "consumes": ["application/json"],
        "parameters": [
          {
            "schema": { "$ref": "#/definitions/comments/items" },
            "in": "body",
            "name": "body",
            "description": "comments",
            "required": true
          }
        ],
        "responses": {
          "201": {
            "description": "successful operation",
            "schema": { "$ref": "#/definitions/comments/items" }
          },
          "400": { "description": "invalid comments" }
        },
        "produces": ["application/json"],
        "tags": ["comments"]
      }
    },
    "/api/comments/{id}": {
      "get": {
        "summary": "/api/comments/{id}",
        "consumes": ["application/json"],
        "parameters": [
          { "name": "id", "in": "path", "required": true, "type": "integer" }
        ],
        "responses": {
          "200": {
            "schema": { "$ref": "#/definitions/comments/items" },
            "description": "successful operation"
          }
        },
        "produces": ["application/json"],
        "tags": ["comments"]
      },
      "put": {
        "summary": "/api/comments/{id}",
        "consumes": ["application/json"],
        "parameters": [
          { "name": "id", "in": "path", "required": true, "type": "integer" },
          {
            "schema": { "$ref": "#/definitions/comments/items" },
            "in": "body",
            "name": "body",
            "description": "comments",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "successful operation",
            "schema": { "$ref": "#/definitions/comments/items" }
          },
          "400": { "description": "invalid ID supplied" },
          "404": { "description": "comments not found" },
          "405": { "description": "Validation exception" }
        },
        "produces": ["application/json"],
        "tags": ["comments"]
      },
      "patch": {
        "summary": "/api/comments/{id}",
        "consumes": ["application/json"],
        "parameters": [
          { "name": "id", "in": "path", "required": true, "type": "integer" },
          {
            "schema": { "$ref": "#/definitions/comments/items" },
            "in": "body",
            "name": "body",
            "description": "comments",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "successful operation",
            "schema": { "$ref": "#/definitions/comments/items" }
          },
          "400": { "description": "invalid ID supplied" },
          "404": { "description": "comments not found" },
          "405": { "description": "Validation exception" }
        },
        "produces": ["application/json"],
        "tags": ["comments"]
      },
      "delete": {
        "summary": "/api/comments/{id}",
        "consumes": ["application/json"],
        "parameters": [
          { "name": "id", "in": "path", "required": true, "type": "integer" }
        ],
        "responses": {
          "200": { "description": "successful operation" },
          "400": { "description": "invalid ID supplied" },
          "404": { "description": "comments not found" }
        },
        "produces": ["application/json"],
        "tags": ["comments"]
      }
    },
    "/api/profile": {
      "get": {
        "summary": "/api/profile",
        "consumes": ["application/json"],
        "parameters": [
          {
            "name": "_page",
            "in": "query",
            "required": false,
            "type": "integer",
            "description": "parameter to return paginated data"
          },
          {
            "name": "_limit",
            "in": "query",
            "required": false,
            "type": "integer",
            "description": "parameter to limit paginated data"
          },
          {
            "name": "_sort",
            "in": "query",
            "required": false,
            "type": "string",
            "description": "sort by attributes"
          },
          {
            "name": "_order",
            "in": "query",
            "required": false,
            "type": "string",
            "description": "order ascending or descending",
            "enum": ["asc", "desc"]
          },
          {
            "name": "_start",
            "in": "query",
            "required": false,
            "type": "integer",
            "description": "parameter to set start sliced data"
          },
          {
            "name": "_end",
            "in": "query",
            "required": false,
            "type": "integer",
            "description": "parameter to set start sliced data"
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "type": "string",
            "description": "full text search"
          },
          {
            "name": "_embed",
            "in": "query",
            "required": false,
            "type": "string",
            "description": "include children resources"
          },
          {
            "name": "_expand",
            "in": "query",
            "required": false,
            "type": "string",
            "description": "include parent resource"
          }
        ],
        "responses": {
          "200": {
            "schema": { "$ref": "#/definitions/profile" },
            "description": "successful operation"
          }
        },
        "produces": ["application/json"],
        "tags": ["profile"]
      },
      "post": {
        "summary": "/api/profile",
        "consumes": ["application/json"],
        "parameters": [
          {
            "schema": { "$ref": "#/definitions/profile" },
            "in": "body",
            "name": "body",
            "description": "profile",
            "required": true
          }
        ],
        "responses": {
          "201": {
            "description": "successful operation",
            "schema": { "$ref": "#/definitions/profile" }
          },
          "400": { "description": "invalid profile" }
        },
        "produces": ["application/json"],
        "tags": ["profile"]
      },
      "put": {
        "summary": "/api/profile",
        "consumes": ["application/json"],
        "parameters": [
          {
            "schema": { "$ref": "#/definitions/profile" },
            "in": "body",
            "name": "body",
            "description": "profile",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "successful operation",
            "schema": { "$ref": "#/definitions/profile" }
          },
          "400": { "description": "invalid ID supplied" },
          "404": { "description": "profile not found" },
          "405": { "description": "Validation exception" }
        },
        "produces": ["application/json"],
        "tags": ["profile"]
      },
      "patch": {
        "summary": "/api/profile",
        "consumes": ["application/json"],
        "parameters": [
          {
            "schema": { "$ref": "#/definitions/profile" },
            "in": "body",
            "name": "body",
            "description": "profile",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "successful operation",
            "schema": { "$ref": "#/definitions/profile" }
          },
          "400": { "description": "invalid ID supplied" },
          "404": { "description": "profile not found" },
          "405": { "description": "Validation exception" }
        },
        "produces": ["application/json"],
        "tags": ["profile"]
      }
    }
  },
  "swagger": "2.0",
  "definitions": {
    "posts": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "format": "int32", "example": 1 },
          "title": { "type": "string", "example": "json-server" },
          "author": { "type": "string", "example": "typicode" }
        }
      }
    },
    "comments": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "format": "int32", "example": 1 },
          "body": { "type": "string", "example": "some comment" },
          "postId": { "type": "integer", "format": "int32", "example": 1 }
        }
      }
    },
    "profile": {
      "type": "object",
      "properties": { "name": { "type": "string", "example": "typicode" } }
    }
  }
}

Expected behavior
I get a graphql schema

@Alan-Cha
Copy link
Collaborator

This is definitely related to our Swagger/OpenAPI validator/convertor, swagger2openapi. I just tried their online tool with your sample Swagger and I got the following validation error:

message: "Cannot resolve reference: #/components/requestBodies/posts/items"
context: "#/paths/~1api~1posts/post/requestBody/%24ref"

I will take a deeper look at this later this week.

This is related to #334, which is on potentially removing this dependency.

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

2 participants