Why isn't Swagger detecting optional JSON properties?

Viewed 594

I have the following class:

import com.fasterxml.jackson.annotation.JsonProperty
import org.joda.time.DateTime
import org.joda.time.DateTimeZone

data class Entity(
        val email: String,
        val name: String,
        val birthDate: DateTime,
        @JsonProperty(required = false) val gender: Gender? = null,
        @JsonProperty(required = false) val country: String? = null,
        val locale: String,
        val disabled: Boolean = false,
        @JsonProperty(required = false) val createdAt: DateTime = DateTime(DateTimeZone.UTC),
        val role: Role,
        val entityTypeId: Long,
        val entityTypeAttributes: MutableMap<String, Any> = HashMap(),
        val medicalSpecialityId: Long? = null,
        val id: Long? = null
)

And some properties are not required, because they are either nullable (gender, country), or they have a default value (createdAt).

However, the generated swagger documentation is as follows:

 "components": {
    "schemas": {
      "Entity": {
        "required": [
          "birthDate",
          "createdAt", <------------ Notice here!
          "disabled",
          "email",
          "entityTypeAttributes",
          "entityTypeId",
          "locale",
          "name",
          "role"
        ],
        "type": "object",
        "properties": {
          "email": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "birthDate": {
            "type": "string",
            "format": "date-time"
          },
          "gender": {
            "type": "string",
            "enum": [
              "MALE",
              "FEMALE",
              "OTHER"
            ]
          },
          "country": {
            "type": "string"
          },
          "locale": {
            "type": "string"
          },
          "disabled": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "role": {
            "type": "string",
            "enum": [
              "ADMIN",
              "DOCTOR",
              "PATIENT"
            ]
          },
          "entityTypeId": {
            "type": "integer",
            "format": "int64"
          },
          "entityTypeAttributes": {
            "type": "object",
            "additionalProperties": {
              "type": "object"
            }
          },
          "medicalSpecialityId": {
            "type": "integer",
            "format": "int64"
          },
          "id": {
            "type": "integer",
            "format": "int64"
          }
        }
      },
   (...)

So in terms of documentation it shows that createdAt is mandatory (which is not true)...

Generated Swagger docs

I am using Kotlin, Javalin and the OpenAPI (io.javalin.plugin.openapi) Javalin integration.

I don't know what more do I need to make OpenAPI understand that createdAt is optional...

1 Answers

My guess would be that the kotlin implementation is using nullability as a way to discover required and ignoring the required property. For example, you shouldn't actually need the annotation for gender and country.

Obviously this is not ideal, but if you change creadtedAt to a DateTime? it would not show as required.

This is likely a bug with the kotlin openapi doc tool that javalin has pulled in.

Related