1 year ago

#366434

test-img

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

Accepted video resources