SMILEY4 / ktor-swagger-ui

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

customProcessor works not properly with 3.5.1 version #144

Closed RaySmith-ttc closed 1 month ago

RaySmith-ttc commented 1 month ago

The type of custom processors turns to null:

data class Foo(val value: BigDecimal)
type
    .collectSubTypes(25)
    .processReflection {
        // ...
        customProcessor<BigDecimal> {
            createDefaultPrimitiveTypeData<BigDecimal>(mutableMapOf(
                "format" to "#.########", "type" to "number"
            ))
        }
    }
    .connectSubTypes()
    .handleNameAnnotation()
    .generateSwaggerSchema()
    .processCustomFormats()
    .handleCoreAnnotations()
    .handleSchemaAnnotations()
    .withAutoTitle(TitleType.SIMPLE)
    .compileReferencingRoot()
private const val SWAGGER_FORMAT = "swagger-format"

inline fun <reified T> createDefaultPrimitiveTypeData(values: MutableMap<String, Any?>): PrimitiveTypeData {
    return PrimitiveTypeData(
        id = TypeId.build(T::class.qualifiedName!!),
        simpleName = T::class.simpleName!!,
        qualifiedName = T::class.qualifiedName!!,
        annotations = mutableListOf(
            AnnotationData(
                name = SWAGGER_FORMAT,
                values = values,
                annotation = null
            )
        )
    )
}

private fun Bundle<SwaggerSchema>.processCustomFormats(): Bundle<SwaggerSchema> {
    fun process(schema: SwaggerSchema) {
        schema.typeData.annotations
            .find { it.name == SWAGGER_FORMAT }
            ?.also { annotation ->
                schema.swagger.format = annotation.values["format"] as String
                schema.swagger.type = annotation.values["type"] as String
            }
    }

    process(data)
    supporting.forEach { process(it) }

    return this
}

3.5.0: image

3.5.1: image

SMILEY4 commented 1 month ago

Hi, could you also show the code for createDefaultPrimitiveTypeData()? Thank you!

RaySmith-ttc commented 1 month ago

Oh, right, I totally forgot that it's not built-in :) I have updated the issue.

SMILEY4 commented 1 month ago

Ah thanks, with the update to openapi 3.1 and schema-kenerator 1.4.2, swagger no longer uses the type property but the types. So changing ...

schema.swagger.type = annotation.values["type"] as String

... to ...

schema.swagger.types = setOf(annotation.values["type"] as String)

... should fix the issue and produce the correct schema:

{
  "root" : {
    "$ref" : "#/components/schemas/io.github.smiley4.schemakenerator.test._ManualTests.Companion.Foo"
  },
  "componentSchemas" : {
    "io.github.smiley4.schemakenerator.test._ManualTests.Companion.Foo" : {
      "type" : "object",
      "properties" : {
        "value" : {
          "type" : "number",
          "format" : "#.########",
          "title" : "BigDecimal"
        }
      },
      "required" : [ "value" ],
      "title" : "Foo"
    }
  }
}
RaySmith-ttc commented 1 month ago

Thank you!