SMILEY4 / ktor-swagger-ui

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

Example in annotation #37

Closed LeatherDeerAU closed 1 year ago

LeatherDeerAU commented 1 year ago

Hi! Now there is a functional of declaring an example for a swager through the creation of an object. But it adds a lot of template code to the routes.

Can we add our own @Example annotation above the DTO fields? Or support swagger @Content annotation, but I'm not sure if the json-schema generator supports it. It seems to me that it looks more appropriate there and doesn't overloads routes.

data class Person(
  @Example("Jack")
  val name: String,
)
SMILEY4 commented 1 year ago

Hi, currently, i am just passing a generic object (Any) to swagger, so im not 100% sure (yet) what this supports and how flexible this is. Also, i am intentiannly trying to keep the dsl/library as annotation free as possible/necessary. I'll check what is possible and what can be done (a @Example swagger-annotation already seems to exist, so maybe not too much has to be changed).

SMILEY4 commented 1 year ago

So, after some research, i think this feature is pretty complex and out of scope for this library. As far as i know, I'd either have to write a java-class-to-swagger-example-conversion-system-thing from scratch, which would not be a trivial task with many edge-cases to cover; or use another third-part library (which i haven't really found yet). Regarding the problem of overloading the routes, the (in my opinion) easiest and clean way would be to offload the examples into another class/file.

Maybe i'll have another look at this in the future - maybe as an extension or addon.

Thanks for the suggestion tough. If you see another option or some way to solve this, please let me know.

chameleon82 commented 1 year ago

That sounds similar to next project for scala (https://github.com/swagger-akka-http/swagger-scala-module):

data class Person(
  @Schema(example = "Jack")
  val name: String,
)

using swagger annotations https://docs.swagger.io/swagger-core/v2.2.0/apidocs/io/swagger/v3/oas/annotations/media/Schema.html#example--

SMILEY4 commented 1 year ago

i think one (simpler option than the one i had in mind) is to have one annotation with the example object only on the top-level class. That way, no reflection-magic is required and the example-definitions would be with the class, not in the routing. Edit: nvm, i forgot that complex annotation-parameters are not allowed in java/kotling.

SMILEY4 commented 1 year ago

After some experimentation, i managed to get it to work with the jsonschema-generator. In its current form, it might be a bit limited and with some edge-cases not working-correctly, but i think as a first step, it could work. I am planning to rework how schhemas are handled in general, which would allow for more refinement or options/features of this type in the future.

The snapshot can be tested with implementation 'com.github.SMILEY4:ktor-swagger-ui:feature~example-annotation-SNAPSHOT'

An example can be found here: ExampleAnnotationExample.kt

I would like to hear your feedback and thoughts on this.

chameleon82 commented 1 year ago

The closest I can find in swagger-core is @ExampleObject

Imo it is important to make design decision here.

One of the ways is to natively support swagger-core annotations. I would prefer that way to avoid support annotations and keep DSL clean and separate. It might be a separate module or even compile dependency bridge (user should provide swagger-core as a dependency to let it work).

Another way (as in SMILEY4's example) is to have own annotations (ktorswaggerui.annotations package might be a better domain separation). It will require more efforts to support, but fully feature request driven solution.

It might be ok to support both as well with ktorswaggerui annotations priority.

Regarding Example(s) annotation it will be great to cover multiple requests/responses examples with example name.

SMILEY4 commented 1 year ago

Another annotation i found is @Schema which i think is closer to what we want/need here. I would propose to support examples via @Schema (maybe in addition to some other possible parameters of this annotation) and the custom and more lightweight/minimal @Example annotation with higher priority. This would then cover the basic need regarding "inline" examples and could then be extended in the future (via more custom annotation or support for more of the core swagger-annotations).