papsign / Ktor-OpenAPI-Generator

Ktor OpenAPI/Swagger 3 Generator
Apache License 2.0
243 stars 42 forks source link

how to implement a repeated request parameter #9

Closed sheepdreamofandroids closed 4 years ago

sheepdreamofandroids commented 4 years ago

I must be missing something completely. My usecase is a simple GET endpoint taking a list of Long ids and returning associated data. I modelled the input parameter "ids" as

data class ProductImagesRequest(@QueryParam("multiple ids.") val ids:List<Long>)

When calling it with parameters like ?ids=1&ids=2&ids=3 I get this error:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.ArrayList<java.lang.Long>` out of VALUE_STRING token

Why would a request parameter be deserialized from xml or json?

I love this library BTW, it's a very elegant solution!

Wicpar commented 4 years ago

Hi,

Thank you for this issue, i know this would happen eventually. Currently only primitive types are implemented since i use the jackson parser as a quick fix, there are no standard parsers for the query parameter standards as far as i know, and the query parameter standards are quite wonky as well. Here is the spec: https://swagger.io/docs/specification/serialization/ Here is the relevant function to change the behavior: https://github.com/papsign/Ktor-OpenAPI-Generator/blob/master/src/main/kotlin/com/papsign/ktor/openapigen/route/OpenAPIRoute.kt#L74

I am quite busy on another project at the moment, feel free to make a pull request, but once finished i can work on it.

sheepdreamofandroids commented 4 years ago

Laying traps for unsuspecting developers so you can get PR's of them. Genius!

I'm not exactly bristling with free time myself, but let me look at it.

Wicpar commented 4 years ago

Haha. I found a library that seems to decode RFC 6570 templates https://github.com/damnhandy/Handy-URI-Templates/pull/54 I'll see if i can implement it rapidly. I wanted to avoid implementing the entire RFC from scratch, but if a library gets the job done the modifications are a matter of a few hours at most.

Wicpar commented 4 years ago

Good and bad news... I can't use the library as is, but i can frankenstein in the proper parsing behavior.

Wicpar commented 4 years ago

After all implementing it from scratch seems a lot faster now. I think i can get it done by 15:00 GMT+2

sheepdreamofandroids commented 4 years ago

Do you intend to let us specify how parameters have to be encoded? Or will you just accept anything the client throws at you?

Wicpar commented 4 years ago

You will have to specify, defaults being according to the openapi spec, but i will try to make it parse anything you throw at it. Some collisions are possible, they will be caught during startup.

Wicpar commented 4 years ago

I Have finished implementing the primitives: implementation 'com.github.papsign:Ktor-OpenAPI-Generator:experimental-parameters-a35e1a0143-1' i will be adding collections and object support very soon

sheepdreamofandroids commented 4 years ago

Wow, you're on fire!

I'll build your branch and see how that works for my usecase. It's really simple, I just need a list of longs, so that shouldn't be a problem. I'll let you know asap.

Wicpar commented 4 years ago

I am working on the lists and arrays, it's a little trickier than primitives.

sheepdreamofandroids commented 4 years ago

Just a brainfart. Shouldn't RFC 6570 be implemented as a format for kotlinx-serialization?

Wicpar commented 4 years ago

nope, ktor doesn't support RFC 6570 parsing, and no library is made to properly parse individual parameters...

Wicpar commented 4 years ago

lists have been added, you can build the latest changes on jitpack

Wicpar commented 4 years ago

objects are next, but i think i will limit the support to data classes in the beginning... It should not be too complicated to extend afterwards. Once that is done i'll clean the whole mess.

Wicpar commented 4 years ago

Deep object support has been added. It does not support empty indices for arrays. Path param objects and form objects are still missing. Appropriate errors are thrown on startup if anything is not implemented.

sheepdreamofandroids commented 4 years ago

Hi, I've been trying to use your branch but it's not yet working for me. Firstly I think you need a 'maven' or 'maven-publish' plugin in gradle to actually generate a pom. The jitpack artifact is only a jar without transitive dependencies. I'm not good with gradle so I'm not sure that is how to fix it. After adding those dependencies manually (reflections and swagger.js) I get a swagger interface, but my List is still seen as a singular Long. Possibly I'm missing some dependencies.

Wicpar commented 4 years ago

If the main library works the test branch should work as well... I'm not quite sure how jitpack works but i am able to use it without declaring those other dependencies. here is the config:

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
    implementation "ch.qos.logback:logback-classic:$logback_version"
    implementation "io.ktor:ktor-server-core:$ktor_version"
    implementation "io.ktor:ktor-server-host-common:$ktor_version"
    implementation "io.ktor:ktor-metrics:$ktor_version"
    implementation "io.ktor:ktor-server-sessions:$ktor_version"
    implementation "io.ktor:ktor-server-netty:$ktor_version"
    implementation "io.ktor:ktor-jackson:$ktor_version"

    implementation 'com.github.papsign:Ktor-OpenAPI-Generator:experimental-parameters-SNAPSHOT'
}
Wicpar commented 4 years ago

@sheepdreamofandroids It's over, it's done... The code is now up to spec and in a clean and maintainable state. I am merging the branch soon after integration testing.

Wicpar commented 4 years ago

I have merged the changes into master and made a release.

sheepdreamofandroids commented 4 years ago

I'm trying to use this in my own project and it just doesn't work. At the same time I created a testcase within your project which works flawlessly. I've not been able to figure out exactly what is the difference. Mostly because I've been in meetings way more than programming. Just to let you know why I didn't react yet.

Wicpar commented 4 years ago

Alright. On my side we successfully updated the dependency simply by setting the version to the new release in the project configuration. Make sure you are also up to date with the kotlin plugin.

sheepdreamofandroids commented 4 years ago

Hi, I had weird effects. First everything worked as expected except for the array parameter and the fact that I couldn't debug my project in Intellij, it would freeze completely. Now I just upgraded to the latest kotlin plugin (1.3.70) and did the same with the ktor dependency (1.3.2) and now nothing really works anymore. I'm assuming that is because of the different ktor versions. Is there a particular reason you stick with 1.2.6? I'm quite new to using ktor, so if I'm upgrading too fast, I really like to know.

Wicpar commented 4 years ago

No reason the ktor version is not updated. Try to use the release version as dependencies, snapshots might break regularly. I'll update the ktor version asap.

Wicpar commented 4 years ago

updated version. https://github.com/papsign/Ktor-OpenAPI-Generator/releases/tag/0.1-beta.2

sheepdreamofandroids commented 4 years ago

Thanks so much for the help. Now it works. The real culprit though was the fact that we are using gson for JSON serialization instead of jackson.