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

Remote references in components/schemas fail to resolve #351

Closed
mtfurlan opened this issue Oct 11, 2023 · 15 comments
Closed

Remote references in components/schemas fail to resolve #351

mtfurlan opened this issue Oct 11, 2023 · 15 comments
Labels
bug Something isn't working

Comments

@mtfurlan
Copy link

I have a openapi spec that works fine on https://editor.swagger.io/ that throws errors with vacuum.

Remote references in paths/.../schema seem fine, but not in components/references/whatever are not.

I can't figure out how to modify the libopenapi tests in ways that don't crash, so I dunno if the issue is with them or not.

The spec:

{             
  "openapi": "3.0.0",
  "info": {       
    "version": "1.0.0",
    "title": "demo thing",
    "description": "demo thing"
  },      
  "paths": {
    "/a": {
      "get": {
        "responses": { 
          "200": {
            "description": "uses an external ref directly",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "https://raw.githubusercontent.com/pb33f/libopenapi/main/test_specs/petstorev3.json#/components/schemas/Pet"
                }
              }
            }
          }
        }
      }
    },
    "/b": {
      "get": {
        "responses": {
          "200": {
            "description": "uses a thing in components/schemas",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SomeThing"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "SomeThing": {
        "$ref": "https://raw.githubusercontent.com/pb33f/libopenapi/main/test_specs/burgershop.openapi.yaml#/components/requestBodies/BurgerRequest"
      }
    }
  }
}

This results in the error:

cannot resolve reference https://raw.githubusercontent.com/pb33f/libopenapi/main/test_specs/burgershop.openapi.yaml#/components/requestBodies/BurgerRequest, it's missing: $https:.['raw.githubusercontent.com'].pb33f.libopenapi.main.test_specs['burgershop.openapi.yaml$'].components.requestBodies.BurgerRequest

If you switch the URLs it still only fails on the SomeThing ref.

I'm running with npx vacuum lint --base . -d $specFile, and I have vacuum version 0.3.13

@daveshanley
Copy link
Owner

This is a bug for sure. I will look into it ASAP. There is an overhaul of the indexing system in libopenapi happening at the moment, which may automatically resolve this once upgraded.

I will keep you posted.

@daveshanley daveshanley added the bug Something isn't working label Oct 12, 2023
@daveshanley
Copy link
Owner

A resolution for this is coming with #357, running this spec through vacuum with a new -u flag, which allows remote files to be fetched, without specifying a baseURL

@daveshanley
Copy link
Owner

Can you try this spec, with the latest version of vacuum, and use the -u flag? There are still some issues I am working out, but you should see progress.

@mtfurlan
Copy link
Author

mtfurlan commented Nov 6, 2023

I'm getting some inconsistent JSON error messages interspersed in the output.
Also it sometimes reports an error, not always at the same time though.

Testing against this which should have no errors:

{
  "openapi": "3.0.0",
  "info": {
    "version": "1.0.0",
    "title": "demo thing",
    "description": "demo thing"
  },
  "servers": [ { "url": "whatever" } ],
  "paths": { 
    "/b": {
      "get": {
        "operationId": "test",
        "responses": {
          "200": {
            "description": "uses a thing in components/schemas",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SomeThing"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "SomeThing": {
        "$ref": "https://raw.githubusercontent.com/pb33f/libopenapi/main/test_specs/burgershop.openapi.yaml#/components/requestBodies/BurgerRequest"
      }
    }
  }
}
version: 0.4.3 | compiled: 2023-11-05T14:43:04Z

I get the output

$ npx vacuum lint --base . -deu swagger.json 


██╗   ██╗ █████╗  ██████╗██╗   ██╗██╗   ██╗███╗   ███╗
██║   ██║██╔══██╗██╔════╝██║   ██║██║   ██║████╗ ████║
██║   ██║███████║██║     ██║   ██║██║   ██║██╔████╔██║
╚██╗ ██╔╝██╔══██║██║     ██║   ██║██║   ██║██║╚██╔╝██║
 ╚████╔╝ ██║  ██║╚██████╗╚██████╔╝╚██████╔╝██║ ╚═╝ ██║
  ╚═══╝  ╚═╝  ╚═╝ ╚═════╝ ╚═════╝  ╚═════╝ ╚═╝     ╚═╝



version: 0.4.3 | compiled: 2023-11-05T14:43:04Z
🔗 https://quobix.com/vacuum | https://github.com/daveshanley/vacuum


 INFO  Linting against 42 rules: https://quobix.com/vacuum/rulesets/recommended
{"time":"2023-11-06T01:19:17.18739656-05:00","level":"ERROR","msg":"unable to locate reference anywhere in the rolodex","reference":"https://raw.githubusercontent.com/pb33f/libopenapi/main/test_specs/burgershop.openapi.yaml#/components/schemas/Burger"}


# Tags Issues

Line / Column | Severity | Message | Rule | Path


# Schemas Issues

Line / Column | Severity | Message | Rule | Path


# Descriptions Issues

Line / Column | Severity | Message | Rule | Path


Category     | Errors | Warnings | Info
Tags         | 0      | 1        | 0
Schemas      | 0      | 1        | 0
Descriptions | 0      | 2        | 0



                                                                     
          Linting passed, but with 4 warnings and 0 informs

Between 0 and 2 of those random JSON lines.

Also, sometimes it reports the error

(332:13)      | error    | cannot resolve reference `#/components/schemas/Burger`, it's missing: $.components.schemas.Burger [332:13] | resolving-references | $.components.schemas.Burger

@daveshanley
Copy link
Owner

Yeah, there is still work to be done here, the code is designed to need a 'base' to resolve from when using remote references, so this use-case where it's trying to figure out where the next set of references are coming from is still unstable.

This will be one of my next upgrades to fix this use-case.

@daveshanley
Copy link
Owner

I feel the fix will be small and simple and it will just click into place - but yeah still a little wobbly. Thank you for bearing with me.

@mtfurlan
Copy link
Author

mtfurlan commented Nov 6, 2023 via email

@daveshanley
Copy link
Owner

Can you try again with v0.4.4

@mtfurlan
Copy link
Author

0.4.4:

  • no errors

0.4.5:

{"time":"2023-11-14T09:48:07.963064647-05:00","level":"ERROR","msg":"client error","error":"Get \"/tmp/vacuumtest/root.yaml\": unsupported protocol scheme \"\""}

both have the schema warning that ideally they shouldn't:

(29:20)       | warning  | `#/components/schemas/SomeThing` is potentially unused or has been orphaned | oas3-unused-component | $.components.schemas.SomeThing

Also 0.4.4 has this warning, but 0.4.5 doesn't:

(30:20)       | warning  | Component `SomeThing` of type `schemas` is missing a description    | component-description | $.components.schemas.SomeThing

@daveshanley
Copy link
Owner

Are you able to share the exact command you're using? I can't re-create it using 0.4.5, are you still using the same specs above?

@daveshanley
Copy link
Owner

daveshanley commented Nov 14, 2023

Also, did you see this? https://quobix.com/vacuum/faq/#q-can-vacuum-just-look-up-remotefile-based-references-by-its-self

If you just want vacuum to figure out where to look for remote files, or local files then just use the -u / --remote flag. It will attempt to locate files locally from the current working directory, or will look up remote references from the remote location defined by the ref.

@mtfurlan
Copy link
Author

The only change to the command I was running was dropping -e cause I saw the warning count change:

npx vacuum lint --base . -du swagger.json

I'm testing against the file in this comment, though I get the same error with the file in the original post.

@mtfurlan
Copy link
Author

$ npx vacuum lint --base . -du swagger.json 


██╗   ██╗ █████╗  ██████╗██╗   ██╗██╗   ██╗███╗   ███╗
██║   ██║██╔══██╗██╔════╝██║   ██║██║   ██║████╗ ████║
██║   ██║███████║██║     ██║   ██║██║   ██║██╔████╔██║
╚██╗ ██╔╝██╔══██║██║     ██║   ██║██║   ██║██║╚██╔╝██║
 ╚████╔╝ ██║  ██║╚██████╗╚██████╔╝╚██████╔╝██║ ╚═╝ ██║
  ╚═══╝  ╚═╝  ╚═╝ ╚═════╝ ╚═════╝  ╚═════╝ ╚═╝     ╚═╝


version: 0.4.5 | compiled: 2023-11-09T13:52:01Z
🔗 https://quobix.com/vacuum | https://github.com/daveshanley/vacuum


 INFO  Linting against 42 rules: https://quobix.com/vacuum/rulesets/recommended
{"time":"2023-11-14T17:00:15.750971525-05:00","level":"ERROR","msg":"client error","error":"Get \"/tmp/vacuumtest/root.yaml\": unsupported protocol scheme \"\""}


# Tags Issues

Line / Column | Severity | Message                                           | Rule           | Path
(11:7)        | warning  | Tags for `get` operation at path `/b` are missing | operation-tags | $.paths./b.get


# Schemas Issues

Line / Column | Severity | Message                                                                     | Rule                  | Path
(29:20)       | warning  | `#/components/schemas/SomeThing` is potentially unused or has been orphaned | oas3-unused-component | $.components.schemas.SomeThing


# Descriptions Issues

Line / Column | Severity | Message                                                             | Rule                  | Path
(11:14)       | warning  | Operation `get` at path `/b` is missing a description and a summary | operation-description | $.paths./b.get


Category     | Errors | Warnings | Info
Tags         | 0      | 1        | 0
Schemas      | 0      | 1        | 0
Descriptions | 0      | 1        | 0



                                                                     
          Linting passed, but with 3 warnings and 0 informs          
                                                                     

100% reproducible, I've been going back and forth between 0.4.4 and 0.4.5.

I'm on x86_64 linux in case it's a platform difference?

@daveshanley
Copy link
Owner

daveshanley commented Nov 15, 2023

Thank you, so let's break this down a little.

This spec uses a single remote ref

{
  "openapi": "3.0.0",
  "info": {
    "version": "1.0.0",
    "title": "demo thing",
    "description": "demo thing"
  },
  "servers": [ { "url": "whatever" } ],
  "paths": { 
    "/b": {
      "get": {
        "operationId": "test",
        "responses": {
          "200": {
            "description": "uses a thing in components/schemas",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SomeThing"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "SomeThing": {
        "$ref": "https://raw.githubusercontent.com/pb33f/libopenapi/main/test_specs/burgershop.openapi.yaml#/components/requestBodies/BurgerRequest"
      }
    }
  }
}

Currently in vacuum v0.4.5, there are two ways to make use of this, the first is to use the new -u / --remote flag, which will attempt to resolve everything automatically.

Option 1: Use the -u / --remote flag.

Here is an example of the same command you're running.

vacuum lint swagger.json -d -u

notice there is no need for the --base flag when running -u

If you do that, then you should see this result.

Screenshot 2023-11-15 at 7 59 15 AM

Notice there are no error logs? vacuum resolved things automatically for you.

Option 2: Use the --base flag to set a base URL.

Only use a file path as a base, if your specs reference local files

The --base flag is used to tell vacuum where to resolve from, if the referenced files are not in the local working directory, OR you want to use a DIFFERENT base URL than the one provided in the spec.

For example, if you want load files from https://NOT-GITHUB.COM/pb33f/libopenapi/main/test_specs/burgershop.openapi.yaml#/components/requestBodies/BurgerRequest instead of https://raw.githubusercontent.com/pb33f/libopenapi/main/test_specs/burgershop.openapi.yaml#/components/requestBodies/BurgerRequest

This is what --base is for.

So, you can get the same effect as the -u flag, by setting the baseURL to https://raw.githubusercontent.com

for example:

vacuum lint swagger.json -d --base https://raw.githubusercontent.com

And you should see this:

Screenshot 2023-11-15 at 8 12 09 AM

To see vacuum try to resolve the references from somewhere else, try a random domain like this:

vacuum lint swagger.json -d --base https://i-am-not-a-real-domain.com

You will see it spew logs saying "dial tcp: lookup i-am-not-a-real-domain.com: no such host"

And then vacuum will tell you things like component '#/components/requestBodies/BurgerRequest' does not exist in the specification

The only time you need to use a filepath with --base, is if your specs cannot be resolved from your working directory and they are somewhere else on the filesystem.

I hope this makes sense.

@mtfurlan
Copy link
Author

That was the issue, not sure why I started doing --base, but without it everything works fine.
Thank you for for both fixing the issue and also telling me what I was doing wrong!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants