SMILEY4 / ktor-swagger-ui

Kotlin Ktor plugin to generate OpenAPI and provide Swagger UI
Apache License 2.0
180 stars 33 forks source link

Generic properties and kotlinsx.serialization #162

Open Huholoman opened 3 days ago

Huholoman commented 3 days ago

Hello, I have api endpoint with Event and the Event has Location. The Locatio is interface with two implementations GeoLocation and OnlineLocation, something like this

@Serializable
sealed interface Location

@Serializable
@SerialName("geo")
data class GeoLocation(val lat: Double, val lot: Double) : Location

@Serializable
@SerialName("online")
data class OnlineLocation(val url: String) : Location

Now default behaviour of kotlinx.serialization is that it adds "type" to the payload, like so

"location": {
  "type": "online",
  "url": "https://twitch.tv/angrytestie"
}

But the "type" is not in generated apidoc.


  "components" : {
    "schemas" : {
      "com.some.app.contracts.Location" : {
        "anyOf" : [ {
          "$ref" : "#/components/schemas/com.some.app.contracts.GeoLocation"
        }, {
          "$ref" : "#/components/schemas/com.some.app.contracts.OnlineLocation"
        } ],
        "title" : "Location"
      },
      "com.some.app.contracts.GeoLocation" : {
        "type" : "object",
        "properties" : {
          "lat" : {
            "type" : "number",
            "format" : "double",
            "title" : "Double"
          },
          "lon" : {
            "type" : "number",
            "format" : "double",
            "title" : "Double"
          }
        },
        "required" : [ "lat", "lon" ],
        "title" : "GeoLocation"
      },
      "com.some.app.contracts.OnlineLocation" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string",
            "url" : "String"
          }
        },
        "required" : [ "url" ],
        "title" : "OnlineLocation"
      },
      "com.some.app.contracts.CreateEventCommand" : {
        "type" : "object",
        "properties" : {
          "location" : {
            "$ref" : "#/components/schemas/com.some.app.contracts.Location"
          },
          "title" : {
            "type" : "string",
            "title" : "String"
          }
        },
        "required" : [ "location", "title" ],
        "title" : "CreateEventCommand"
      }
    },

Is it possible get this type of generic properties in generated apidoc? Not sure, add it to all component implementing localization, or through Location component definition?

  "Location": {
    "allOf": [
      {
        "type": "object",
        "required": ["type"],
        "properties": {
          "type": {
            "type": "string",
            "description": "Specify location type",
            "enum": ["geo", "online"]
          }
        }
      },
      {
        "anyOf": [
          {
            "$ref": "#/components/schemas/OnlineLocation"
          },
          {
            "$ref": "#/components/schemas/GeoLocation"
          }
        ]
      }
    ]
  },

Thank you for your advice in advance.