seriousme / fastify-openapi-glue

A plugin for the Fastify webserver to autogenerate a Fastify configuration based on a OpenApi(v2/v3) specification.
MIT License
196 stars 33 forks source link

"Error: 'specification' parameter must contain a valid version" when trying to reference schema from another file #560

Closed matan-mitiga closed 4 months ago

matan-mitiga commented 5 months ago

Hi, thank you for this wonderful package. I've encountered an issue when trying to reference a schema from another file, like this:

...
  "components": {
    "schemas": {
      "SomeSchema": {
        "$ref": "./schemas/aws/SomeSchema.json"
      },
...
}

The schema is a valid OAI3 schema:

{
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "Name": {
        "type": "string"
      }
   }
}

When I try to run the server I get the following error:

Error: 'specification' parameter must contain a valid version 2.0 or 3.0.x or 3.1.x specification
 ❯ Parser.parse ../../../node_modules/fastify-openapi-glue/lib/Parser.js:49:10
 ❯ plugin ../../../node_modules/fastify-openapi-glue/index.js:122:17

When I use an inline schema it works.

What can be the issue?

I'm using the latest: fastify-openapi-glue@4.4.3

seriousme commented 5 months ago

Hi,

thanks for asking!

The challenge you have is that JSONschema behaves a bit differently than HTML when it comes to references. A $ref does not automatically include the file it is pointing at, it merely references another schema. To be exact: HTML uses Uniform Resource Locators (URL) where JSON schema uses Uniform Resource Identifiers (URI).

So when you write: "$ref": "./schemas/aws/SomeSchema.json" It will try to find a piece of schema with "$id": "./schemas/aws/SomeSchema.json" where $id contains the URI.

The JSON schema specification has a page on schema structuring that explains it in more detail.

This info might be interesting to read, but it does not directly solve your problem. There are two ways to solve this using fastify-openapi-glue 1) the quick and dirty way: read both files in JSON objects and replace the "$ref" attribute in the first file by the JSON object from the second file. however this assumes that you know upfront which "$ref" you need to replace.

2) using https://github.com/seriousme/openapi-schema-validator openapi-schema-validator has a \<instance>.addSpecRef(subSpecification, uri) method which allows you to add any number of subSpecifications (in YAML or JSON format) . Now as long as the URI's in the "$Ref"'s in the calling schema match the "$id"'s in the subschema you can then retrieve an inlined schema with all the subschema's in the right place.

If you then feed the resulting schema to fastify-openapi-glue you should be good to go!

Kind regards, Hans ps. I will add a note to the README.md of fastify-openapi-glue as I presume there will be more people with this question. So again thanks for asking !

seriousme commented 5 months ago

FYI: I just added a note referring to: subSchemas.md to README.md

matan-mitiga commented 5 months ago

@seriousme thank you for the fast response. I currently solved my issue by bundling the spec file into a single file using swagger-cli. Using addSpecRef can be a bit of a hustle if I have too many refs. Would be happy to see this feature built in in the library :)

seriousme commented 5 months ago

If we treat URI's as URL's then we are opening a whole can of worms Some examples that should then also work:

The way that swagger-cli resolves its references without $id in subschemas might be convenient, however its non-standard :-(

So I currently have no plans to include a similar mechanism in fastify-openapi-glue.

Kind regards, Hans

seriousme commented 5 months ago

FYI: I have added bundling functionality to https://github.com/seriousme/openapi-schema-validator See:

https://github.com/seriousme/openapi-schema-validator?tab=readme-ov-file#cli-for-api-bundling

and:

https://github.com/seriousme/openapi-schema-validator?tab=readme-ov-file#instancevalidatebundlespecificationsubspecification-

Hope this helps

github-actions[bot] commented 4 months ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days'