SMILEY4 / ktor-swagger-ui

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

Fix getSimpleTypeName on SchemaDefinition. E.g. handling of List<*> #52

Closed till1993 closed 1 year ago

till1993 commented 1 year ago

Hi all,

I hope this message finds you well. I wanted to bring your attention to a bug that was introduced in version 2.0.0, which affects the functionality when returning a List, for example.

During the generation process, the schema name is resolved as List<*>, resulting in the following representation:

        "200" : {
          "description" : "",
          "headers" : { },
          "content" : {
            "application/json" : {
              "schema" : {
                "type" : "array",

                "items" : {
                  "$ref" : "#/components/schemas/kotlin.collections.List<de.example.Cat>"
                }
              }
            }
          }
        }

However, the expected behavior, as seen in version 1.*, should be:

        "200" : {
          "description" : "",
          "headers" : { },
          "content" : {
            "application/json" : {
              "schema" : {
                "type" : "array",

                "items" : {
                  "$ref" : "#/components/schemas/de.example.Cat"
                }
              }
            }
          }
        }

This Pull Request addresses this issue and fixes the bug. Please let me know if you have any questions or require further information.

SMILEY4 commented 1 year ago

Hi, thank you for reporting the issue! However, i am having trouple reproducing the bug mystelf. Maybe im missing something, but e.g. looking at the Petstore-example, the generated json looks fine i think. Could you maybe provide a minimal example showing the problem ?

till1993 commented 1 year ago

Hi,

Minimal example to reproduce the issue: https://github.com/till1993/ktor-sample The following OpenAPI is generated: https://github.com/till1993/ktor-sample/blob/main/generated_openapi.json

Thank you for your quick response :-) Hope you can reproduce it now

SMILEY4 commented 1 year ago

Thanks! Sorry for keeping you waiting. I do see the issue now, however after some diging and as far as i understand it - i think the root cause lies somewhere else.

In SchemaContext.kt:

    private fun unwrapRootArray(key: SchemaKeyWrapper, schemaDefinitions: SchemaDefinitions) {
        //...
        val rootName = schemaName(key) // <== BUG: currently returns "...List<Cat>", but should just be "Cat"
        addToComponentsSection(rootName, schemaDefinitions.root.items) // used here for the name of the items
        addInline(key, Schema<Any>().also { array ->
            array.type = "array"
            array.items = Schema<Any>().also { item ->
                item.`$ref` = "#/components/schemas/$rootName"  // used here to reference the items
            }
        })
    }

One way to fix this could be to get the correct element type from the "array"-type, something like this:

val rootName = getWrappedSchemaName(key)

//...

private fun getWrappedSchemaName(key: SchemaKeyWrapper): String {
    return if (key.isCustom) {
        key.schemaId
    } else {
        key.type // type = "...List<Cat>""
            .arguments[0].type!! // get just "Cat"  (i think - maybe there is a cleaner way)
            .getSimpleTypeName() // get the name as string
    }
}
SMILEY4 commented 1 year ago

Hi, the bug was fixed in the latest version 2.2.1 (which should be ready to download soon). Thanks again for reporting and explaining the issue 👍