Skip to content

$ref is trying to fetch URIs and fails #7132

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

Closed
saikiranchalla1 opened this issue Mar 29, 2021 · 1 comment
Closed

$ref is trying to fetch URIs and fails #7132

saikiranchalla1 opened this issue Mar 29, 2021 · 1 comment

Comments

@saikiranchalla1
Copy link

Q&A (please complete the following information)

  • OS: [e.g. macOS]: macOS
  • Browser: [e.g. chrome, safari]: Chrome
  • Version: [e.g. 22]: 89.0.4389.90 (Official Build) (x86_64)
  • Method of installation: [e.g. npm, dist assets]: npm
  • Swagger-UI version: [e.g. 3.10.0]: swagger-ui-express (4.1.6)
  • Swagger/OpenAPI version: [e.g. Swagger 2.0, OpenAPI 3.0]: Swagger 2.0

Content & configuration

Example Swagger/OpenAPI definition:

# your YAML here
{
    "swagger": "2.0",
    "info": {
        "description": "Test Service",
        "version": "1.0.0",
        "title": "Tasks API"
    },
    "schemes": ["http", "https"],
    "host": "localhost:8080",
    "basePath": "/",
    "paths" : {
        "/ping" : {
            "get" : {
                "summary" : "Get the status of the service",
                "description": "Returns the status of the service.",
                "produces": ["application/json"],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "successful operation",
                        "schema": {
                            "type": "array",
                            "items": {
                                "$ref": "#/definitions/pingResponse"
                            }
                        }
                    }
                }
            }
        },
        "/index" : {
            "post" : {
                "summary" : "Index",
                "description": "Index",
                "produces": ["application/json"],
                "responses": {
                    "200": {
                        "description": "successful operation",
                        "schema": {
                            "type": "object",
                            "items": {
                                "$ref": "#/definitions/indexResponse"
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid status value",
                        "schema": {
                            "$ref": "#/definitions/InvalidResponse"
                        }
                    }
                }
            }
        }
    }, 
    "definitions": {
        "pingResponse": {
            "type": "object",
            "properties": {
                "status": {
                     "type": "string"
                }
            }
        },
        "indexResponse": {
  "meta:license": [
    "Copyright 2020 XXXXXXXXXXX Systems Incorporated. All rights reserved.",
    "This work is licensed under a YYYYYYYYY Commons Attribution 4.0 International (CC BY 4.0) license",
    "you may not use this file except in compliance with the License. You may obtain a copy",
    "of the License at https://YYYYYYYYYcommons.org/licenses/by/4.0/"
  ],
  "$schema": "http://json-schema.org/draft-06/schema#",
  "$id": "http://ns.XXXXXXXXXXX.com/XXXXXXXXXXXcloud/repository/index",
  "type": "object",
  "title": "Index Document",
  "description": "An Index Document enumerates the list of discoverable regions, and points to the given user's Assigned Directories. It also contains the singular links defined by the Platform API.",
  "definitions": {
    "assigned-dir-resources": {
      "properties": {
        "_embedded": {
          "type": "object",
          "properties": {
            "http://ns.XXXXXXXXXXX.com/XXXXXXXXXXXcloud/rel/metadata/repository": {
              "$ref": "http://ns.XXXXXXXXXXX.com/XXXXXXXXXXXcloud/repository/repository-metadata"
            },
            "http://ns.XXXXXXXXXXX.com/XXXXXXXXXXXcloud/rel/repository": {
              "$ref": "http://ns.XXXXXXXXXXX.com/XXXXXXXXXXXcloud/repository"
            }
          },
          "required": [
            "http://ns.XXXXXXXXXXX.com/XXXXXXXXXXXcloud/rel/metadata/repository"
          ]
        }
      },
      "required": ["_embedded"]
    },
    "indexdoc": {
      "properties": {
        "repo:regions": {
          "type": "array",
          "items": {
            "type": "string",
            "title": "Region Identifier",
            "description": "The value for region identifier must be one of the valid entries present in [Hosting Location Naming Standards](#Hosting-Location-Naming-Standards)"
          },
          "title": "Regions",
          "description": "Lists the regions where discoverable assets for the user are located."
        },
        "_links": {
          "$ref": "http://ns.XXXXXXXXXXX.com/XXXXXXXXXXXcloud/repository/links#/definitions/resolve-and-ops-links",
          "required": [
            "http://ns.XXXXXXXXXXX.com/XXXXXXXXXXXcloud/rel/resolve/id",
            "http://ns.XXXXXXXXXXX.com/XXXXXXXXXXXcloud/rel/resolve/path",
            "http://ns.XXXXXXXXXXX.com/XXXXXXXXXXXcloud/rel/ops"
          ]
        },
        "children": {
          "type": "array",
          "items": {
            "type": "object",
            "$ref": "#/definitions/assigned-dir-resources"
          },
          "description": "An enumeration of assigned directories for the given user."
        }
      }
    }
  },
  "allOf": [
    {
      "$ref": "#/definitions/indexdoc"
    }
  ],
  "required": ["_links", "repo:regions"]
},
        "Task": {
            "type": "object",
            "properties": {
                "task": {
                    "type": "string"
                },
                "assignee": {
                    "type": "string"
                },
                "status": {
                    "type": "string"
                }
            }
        },
        "InvalidResponse": {
            "type": "object",
            "properties": {
                "statusCode": {
                    "type": "string"
                },
                "message": {
                    "type": "string"
                }
            }

        }
    }
}

Swagger-UI configuration options: None

SwaggerUI({
  // your config options here
})
?yourQueryStringConfig

Describe the bug you're encountering

I have a few schemas that I'm using in a Swagger doc. The schemas reference other schemas using $ref by providing URIs. Those URIs are only identifiers and do not contain anything. As per JSON schema spec: Even though the value of a $ref is a URI-reference, it is not a network locator, only an identifier. This means that the schema doesn’t need to be accessible at the resolved URI, but it may be. It is basically up to the validator implementation how external schema URIs will be handled, but one should not assume the validator will fetch network resources indicated in $ref values..

I have the following 2 questions:

  1. The actual schemas exist in a Git repo and have an $id field as a URI to uniquely identify the schema. The same URIs are referenced in the schemas used in Swagger doc. Is there a way to load all the schemas from a folder or a remote location and have $ref reference them using the URI identifiers?
  2. Since $ref is trying to fetch the remote URI, is there a way to turn it off?

To reproduce...

Steps to reproduce the behavior:
1.Save the above Swagger to swagger.json
2. Use the following snippet in a NodeJS express application to load Swagger:

const express = require('express');
const swaggerUi = require('swagger-ui-express');
const swaggerDocument = require('./swagger.json');

// App
const app = express();
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));

Expected behavior

$ref should treat URIs with HTTP(s) starts as IDs and should not try to fetch them.

Screenshots

image

Additional context or thoughts

@hkosova
Copy link
Contributor

hkosova commented Mar 30, 2021

OpenAPI 2.0 uses an extended subset of JSON Schema Draft 4 rather than a full JSON Schema. One of the differences is that $id is not supported, and so schema $refs must be network-resolvable.

Full JSON Schema compatibility was added in OpenAPI 3.1 but this version is not yet supported (see #5891).


Since you're using OAS2, you need to fix your schema to make it compatible with OpenAPI Schema Object:

  • make $refs resolvable and/or embed those external schemas into the definitions section of your OpenAPI file,
  • remove the $schema and $id keywords,
  • move definitions from the schema to the OpenAPI definitions section,
  • add the x- prefix to meta:license (arbitrary keywords need the x- prefix).

You can use https://editor.swagger.io to validate the syntax.

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

No branches or pull requests

2 participants