Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to implement a repeated request parameter #9

Closed
sheepdreamofandroids opened this issue Feb 25, 2020 · 25 comments
Closed

how to implement a repeated request parameter #9

sheepdreamofandroids opened this issue Feb 25, 2020 · 25 comments

Comments

@sheepdreamofandroids
Copy link

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
Copy link
Collaborator

Wicpar commented Feb 25, 2020

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
Copy link
Author

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
Copy link
Collaborator

Wicpar commented Feb 27, 2020

Haha.
I found a library that seems to decode RFC 6570 templates
damnhandy/Handy-URI-Templates#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
Copy link
Collaborator

Wicpar commented Feb 27, 2020

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

@Wicpar
Copy link
Collaborator

Wicpar commented Feb 27, 2020

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

@sheepdreamofandroids
Copy link
Author

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
Copy link
Collaborator

Wicpar commented Feb 27, 2020

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
Copy link
Collaborator

Wicpar commented Feb 27, 2020

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
Copy link
Author

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
Copy link
Collaborator

Wicpar commented Feb 27, 2020

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

@sheepdreamofandroids
Copy link
Author

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

@Wicpar
Copy link
Collaborator

Wicpar commented Feb 27, 2020

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

@Wicpar
Copy link
Collaborator

Wicpar commented Feb 27, 2020

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

@Wicpar
Copy link
Collaborator

Wicpar commented Feb 27, 2020

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
Copy link
Collaborator

Wicpar commented Feb 28, 2020

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
Copy link
Author

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
Copy link
Collaborator

Wicpar commented Mar 2, 2020

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
Copy link
Collaborator

Wicpar commented Mar 4, 2020

@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
Copy link
Collaborator

Wicpar commented Mar 4, 2020

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

@Wicpar Wicpar closed this as completed Mar 4, 2020
@sheepdreamofandroids
Copy link
Author

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
Copy link
Collaborator

Wicpar commented Mar 10, 2020

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
Copy link
Author

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
Copy link
Collaborator

Wicpar commented Mar 18, 2020

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
Copy link
Collaborator

Wicpar commented Mar 19, 2020

@sheepdreamofandroids
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants