2 years ago
#366434

Jan
How to generate oneOf using springdoc from a Kotlin sealed class
I have an existing Kotlin model which is a sealed class
sealed class AnyShape(val type: ShapeType) {
    enum class ShapeType { Square,  Circle }
    
    data class Square(val size: Float) : AnyShape(ShapeType.Square)
    data class Circle(val radius: Float) : AnyShape(ShapeType.Circle)
}
My existing, manually written OpenAPI spec defines this model using the oneOf to express the polymorphism:
components:
  schemas:
    AnyShape:
      discriminator:
        propertyName: type
      oneOf:
      - $ref: '#/components/schemas/Square'
      - $ref: '#/components/schemas/Circle'
    Circle:
      required:
      - radius
      - type
      type: object
      properties:
        radius:
          type: number
          format: float
    Square:
      required:
      - size
      - type
      type: object
      properties:
        size:
          type: number
          format: float
Now, instead of maintaining the yaml spec manually, I'd like to generate it from the Kotlin code using springdoc-openapi so I annotated my AnyShape as follows:
@Schema(
    oneOf = [AnyShape.Square::class, AnyShape.Circle::class],
    discriminatorProperty = "type"
)
sealed class AnyShape {
    @Schema(enumAsRef = true)
    enum class ShapeType { Square, Circle }
    data class Square(val size: Float) : AnyShape() {
        val type = ShapeType.Square
    }
    data class Circle(val radius: Float) : AnyShape() {
        val type = ShapeType.Circle
    }
}
However the generated yaml spec is not what I'd expect because the main AnyShape is of type object but I'd like to be just the oneOf type (as above)
omponents:
  schemas:
    AnyShape:
      type: object  # <<<< THIS
      discriminator:
        propertyName: type
      oneOf:
      - $ref: '#/components/schemas/Square'
      - $ref: '#/components/schemas/Circle'
    Circle:
      required:
      - radius
      - type
      type: object
      properties:
        radius:
          type: number
          format: float
        type:
          $ref: '#/components/schemas/ShapeType'
    ShapeType:
      type: string
      enum:
      - Square
      - Circle
    Square:
      required:
      - size
      - type
      type: object
      properties:
        size:
          type: number
          format: float
        type:
          $ref: '#/components/schemas/ShapeType'
How could I achieve that the generated yaml is the same as the one I initially wrote manually (1st example)
kotlin
swagger
openapi
springdoc
0 Answers
Your Answer