VaporToOpenAPI icon indicating copy to clipboard operation
VaporToOpenAPI copied to clipboard

Optional enum property not marked as nullable in generated OAS

Open barnabashomola opened this issue 6 months ago • 4 comments

Hi,

I have an enum that looks like the one below. The package correctly generates it as a schema and uses the $ref in the enclosing struct.

However, in the enclosing struct, the enum property is optional, so it should be marked as nullable in the OpenAPI specification — but that’s not the case. Am I doing something wrong?

For comparison, the other optional properties in the struct (that are not $refs) are correctly marked as nullable.

Enum:

import SwiftOpenAPI

enum TestEnum: String, CaseIterable {
    case testA = "TestA"
    case testB = "TestB"
}

extension TestEnum: OpenAPIType {
    static var openAPISchema: SchemaObject {
        .enum(of: .string, cases: allCases.map { .string($0.rawValue) })
            .with(\.description,
                  """
                    - "TestA": Description for TestA.
                    - "TestB": Description for TestB.
                  """)
    }
}

Struct that uses it:

import Vapor
import VaporToOpenAPI

struct TestStruct: Content {
    var boolProp: Bool?
    var enumProp: TestEnum?
}

Relevant OAS output:

"boolProp": {
  "type": "boolean",
  "nullable": true
},
"enumProp": {
  "$ref": "#/components/schemas/TestStruct"
},

barnabashomola avatar Oct 31 '25 12:10 barnabashomola

I will check

dankinsoid avatar Nov 01 '25 16:11 dankinsoid

I will check

Hey @dankinsoid, any update on this? :)

BAHO-TM avatar Nov 13 '25 10:11 BAHO-TM

@BAHO-TM , @barnabashomola I made some research:

  1. OpenAPI itself doesn't support nullable ref: https://github.com/OAI/OpenAPI-Specification/issues/1368
  2. OpenAPI enums must contain 'null' in cases to be nullable: https://github.com/OAI/OpenAPI-Specification/issues/1900

I will add support

 "snippet2": {
    "anyOf": [
      { "$ref": "#/properties/snippet" },
      { "type": "null" }
    ]
  }

for nullable references but I'm not sure that codegen tools will proccess it correctly

dankinsoid avatar Nov 13 '25 11:11 dankinsoid

@barnabashomola @BAHO-TM Also, the main mechanic to mark optionals for objects is excluding from "required" property

so for

struct TestStruct: Content {
    var boolProp: Bool
    var enumProp: TestEnum?
}

you should get

{
  "type": "object",
  "properties": {
    "boolProp": {
      "type": "boolean"
    },
    "enumProp": {
      "$ref": "#/components/schemas/TestStruct"
   }
  },
  "required": [
    "boolProp" // <<------- no "enumProp" here
  ],
  "additionalProperties": false
}

dankinsoid avatar Nov 13 '25 12:11 dankinsoid