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

feat(openapi): support OpenAPI version 3.1 #882

Open
wants to merge 20 commits into
base: master
Choose a base branch
from

Conversation

SF97
Copy link

@SF97 SF97 commented Jan 1, 2024

This PR circumvents AJV issue by replacing all $dynamicAnchor keywords in OpenAPI schema with a direct reference, using $ref. This has been suggested by @Jackman3005 in #573 (comment), which originally came from @seriousme, which already made this workaround in his own OpenAPI schema validation library, https://github.com/seriousme/openapi-schema-validator. From what I understand this shouldn't be an issue. Using $dynamicAnchor would allow this lib to replace OpenAPI specification definitions, which it does not do.

Changes

  • openapi.schema.validator.ts now creates a different AJV instance that supports JSON schema 2020-12 when it detects version 3.1. This AJV instance accepts the format media-range but does not validate its content. This validation can be made in another PR
  • Adds OpenAPI specification 3.1 with $dynamicAnchor references changed to $ref
  • Change test scripts to use Mocha's --extension flag. With the previous setup, the new tests weren't being picked up by the runner

OpenAPI 3.1 support

  • Support webhook property without any defined paths
  • Support an API with only components
  • Fully complete Open API 3.1 schema in type.ts
  • Support "summary" in Info Object
  • Support "identifier" field for SPDX licenses in License Object
  • Ensure "nullable" property does not work anymore. Null type works instead
  • Ensure Request Body validation works in GET HTTP methods
  • Ensure "default" must exist in server variable "enum" values
  • Ensure it is possible to create an Operation Object without responses
  • Support "pathItems" in Components Object

There are some more changes introduced by Open API 3.1, but they're schema changes that are validated by AJV, so tests, although important, aren't as critical as the ones above. They are:

  • Ensure mutual TLS works correctly
  • Ensure extension prefixed with "x-oas-" is not allowed
  • Ensure "exclusiveMaximum" and "exclusiveMinimum" do not accept boolean values
  • Ensure server variable "enum" can not be empty
  • Ensure "jsonSchemaDialect" is supported
  • Ensure "style", "explode" and "allowReserved" for multipart/form-data are allowed as media types

Closes #573 #755

@SF97 SF97 mentioned this pull request Jan 1, 2024
@cdimascio
Copy link
Owner

Thank you! can you help build the scaffolding and establish a pattern for 3.1 tests, enabling myself and the community to contribute and expand on them

@SF97
Copy link
Author

SF97 commented Jan 31, 2024

Thank you! can you help build the scaffolding and establish a pattern for 3.1 tests, enabling myself and the community to contribute and expand on them

Yes, I can do that! I've been really busy lately so I haven't got around to that yet

I think I'll have to time to pick it up this weekend

…ck up subdirectories

Mocha was not picking up the tests in subdirectories with the provided glob. Adding --extension with
the tests extension and setting the root test folder in tests fixed it
@SF97
Copy link
Author

SF97 commented Feb 5, 2024

Hello!

I just pushed the first test for OpenAPI 3.1, where we test for webhook support without any API routes, in which I found some bugs immediately 🤣 but at least I was able to fix it and the tests are passing 🥳

I created the folder test/openapi_3.1 for version 3.1 related tests. I've also added the interface DocumentV3_1 for a OpenAPI 3.1 compatible type, and refactored all references to the OpenAPI document to union both 3.0 and 3.1. I found this pretty ugly, maybe we should create an abstraction around it. Anyway, what I wanted was to at least do the first tests so we can all contribute to this PR :)

I also added an (incomplete) list of things to support in OpenAPI 3.1

I'll try to contribute as much as I can in the upcoming days. Anything that I can help with, just let me know

@SF97 SF97 marked this pull request as draft February 5, 2024 00:49
Copy link
Owner

@cdimascio cdimascio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks good. one question regarding apiDocs.paths i.e. why might it be missing and what is the behavior when it is

@SF97
Copy link
Author

SF97 commented Feb 29, 2024

Hello

Just added the list of things we need to ensure that work in OpenAPI 3.1. I based it on OpenAPI's own changelog. I'm currently adding tests to ensure that everything works with the 3.1 spec just fine. Just added some and I'm happy to receive contributions :)

@SF97 SF97 marked this pull request as ready for review April 28, 2024 18:46
@SF97
Copy link
Author

SF97 commented Apr 28, 2024

Hello @cdimascio

I've added the most important tests. There are some more things to validate, but they're assured by AJV, thus I don't think they're critical to have this feature.

But I need help in one thing before shipping. I've added a test to ensure that pathItems is supported in components object, but it's failing. The YAML (test/openapi_3.1/resources/components_path_items.yaml) is fine, since it's parsed correctly in https://editor-next.swagger.io/, and it's according to the spec, but AJV is saying it's invalid, and I'm not sure why. It throws this error:
image

Can you give a little help here to ensure that we'll support this feature? After this test is passing we can proceed with a full review and add support for OpenAPI 3.1 🥳

Thank you

@medranocalvo
Copy link

Can you give a little help here to ensure that we'll support this feature? After this test is passing we can proceed with a full review and add support for OpenAPI 3.1 🥳

Had a look at this. As far as I understand the YAML is invalid, and swagger-editor is being lax about it.

Looking at the 3.1 schema https://github.com/cdimascio/express-openapi-validator/pull/882/files#diff-380b880ffe3121cfdcd466e6bc447b3607d1ddaea014b3167b3b9ee12611fd1e line 286, we see:

    "paths": {
      "$comment": "https://spec.openapis.org/oas/v3.1.0#paths-object",
      "type": "object",
      "patternProperties": {
        "^/": {
          "$ref": "#/$defs/path-item"
        }
      },
      "$ref": "#/$defs/specification-extensions",
      "unevaluatedProperties": false
    },

where in line 268:

        "pathItems": {
          "type": "object",
          "additionalProperties": {
            "$ref": "#/$defs/path-item-or-reference"
          }
        }

That is, paths' elements must be "#/$defs/path-item", while pathItems' elements might also be references. The yaml looks like this:

openapi: 3.1.0
info:
  title: Example specification
  version: "1.0"
servers:
  - url: /v1
components:
  pathItems: 
    entity:
      get: 
        [...]
paths:
  /entity:
    $ref: '#/components/pathItems/entity'

We try to use a reference from paths to components/pathItems, where they are only allowed in the other direction.


@SF97, thank you very much for working on this.

@SF97
Copy link
Author

SF97 commented May 13, 2024

@medranocalvo

Thank you very much! I took a look at the schema, and it looks like it was a bug at the schema level, which has been fixed in OAI/OpenAPI-Specification#3355, i.e. the YAML was fine, but the schema wasn't validating it correctly. I've updated the schema to the newest, and it no longer throws a schema error 😎.

The test is still failing, but I suspect what it is... I'm going to work on it

@SF97
Copy link
Author

SF97 commented May 16, 2024

And it is fixed :) All tests are passing

That means this PR is complete AFAIK and can be reviewed and merged to fully support Open API 3.1, including reusable path items which I just fixed

@cdimascio could you please review and let me know if there's anything that needs to be changed?

@medranocalvo
Copy link

Reviewed lightly and added a couple of comments. Hope it helps.

@cdimascio
Copy link
Owner

Thank you

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

Successfully merging this pull request may close these issues.

OpenAPI 3.1 support
3 participants