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

Support for nullable property in OpenAPI 3 #86

Open
Droidion opened this issue Dec 22, 2023 · 4 comments
Open

Support for nullable property in OpenAPI 3 #86

Droidion opened this issue Dec 22, 2023 · 4 comments

Comments

@Droidion
Copy link

I have model defined like

t.Object({
  numericProp: t.Nullable(t.Number()),
})

This generates expected type TUnion<[TNumber, TNull]>.

And in OpenAPI I'm getting

"numericProp": {
  "anyOf": [
    {
      "type": "null"
    },
    {
      "type": "number"
    }
  ]
}

OpenAPI spec says

OpenAPI 3.0 does not have an explicit null type as in JSON Schema, but you can use nullable: true to specify that the value may be null. Note that null is different from an empty string "".

So, the expected OpenAPI schema would be

"numericProp": {
  "type": "null",
  "nullable": true
}

SwaggerUI also has problem rendering model example, saying "numericProp": "Unknown Type: null",

@bostjanpisler
Copy link

workaround I'm using for null

t.Object({ numericProp: t.Union([t.Number(), t.Null()]) })

@Mudbill
Copy link

Mudbill commented Jan 6, 2024

Came to report this same issue. You'd think that t.Nullable(t.String()) would generate the correct type for the UI. Instead it appears as this:

image image

Reading the spec, it appears that OpenAPI v3.1 uses a union of null and X to represent this (which is correctly done), but maybe the included version of SwaggerUI doesn't support 3.1.

Maybe this is simply a mismatch of the expected OpenAPI version between @elysiajs/swagger and elysia itself? (since t comes from the main package)

@Mudbill
Copy link

Mudbill commented Jan 6, 2024

Okay so I discovered something in plain sight that actually seems to have a big impact.

Since the null union is a OpenAPI 3.1 feature (not 3.0), it is of course important that SwaggerUI is parsing 3.1. However, the default seems to be 3.0.

Default and incorrect setup

Notice how it says "OAS 3.0" in the green badge up top of the web page.

const app = new Elysia()
  .use(swagger())
  .post("/", () => "Hello Elysia", {
    body: t.Object({
      nullableString: t.Nullable(t.String()),
    }),
  })
  .listen(3000);
image

Changing the OpenAPI version for Swagger seems to make it handle the correct types that elysia.t generates.

Corrected version matching

const app = new Elysia()
  .use(
    swagger({
      documentation: {
        openapi: "3.1.0", // Add this
      },
    })
  )
  .post("/", () => "Hello Elysia", {
    body: t.Object({
      nullableString: t.Nullable(t.String()),
    }),
  })
  .listen(3000);
image image

I think the suggested fix here is to use 3.1.0 as the default version for Swagger unless otherwise specified, to be in sync with what the default format is from the schema generation. But perhaps there's some important reason why 3.0.3 is used instead that I'm not aware of.

@Droidion
Copy link
Author

Droidion commented Jan 7, 2024

Yes, @Mudbill has the proper good workaround, worked for me. I also agree, that maybe 3.1.0 should be default version, and/or docs can say something about recommended version.

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

3 participants