kotlinserializationktorcontent-negotiation

receiveParameters() fails in ktor


In the ktor app, I'm trying to read posted parameters like this :

val params = call.receiveParameters()

But I'm facing this error :

No Default Transformations found for class io.ktor.utils.io.ByteBufferChannel and expected type TypeInfo(type=class io.ktor.http.Parameters, reifiedType=interface io.ktor.http.Parameters, kotlinType=io.ktor.http.Parameters) for call /...
io.ktor.server.plugins.BadRequestException: Failed to convert request body to class io.ktor.http.Parameters

I'm using ktor 3.0.0-beta-1, also I installed the Content Negotiation like this :

install(ContentNegotiation) {
    gson {}
    json(Json {
            prettyPrint = true
            isLenient = true
            ignoreUnknownKeys = true
        })
}

And I'm sending POST request to the app like this (using Axios):

axios.post(
    `http://127.0.0.1:8080/api/...`,
    {
    a:"1",
    b:"2"
  },{})

Since I'm sending simple pairs of string keys and values, temporarily I'm using the below solution, and It works :

 val paramsMap = call.receive<Map<String,String>>()

What is the correct way to solve this problem !?


Solution

  • receiveParameters is for reading form data - application/x-www-form-urlencoded or multipart/form-data. I'm not that familiar with axios, but the request you sent seems to just be application/json.

    An example of a HTTP request that can be received using receiveParameters can be found here.

    POST http://localhost:8080/signup
    Content-Type: application/x-www-form-urlencoded
    
    username=JetBrains&email=example@jetbrains.com&password=foobar&confirmation=foobar
    

    To see how to send a x-www-form-urlencoded with axios, see this post.

    If you just want to send JSON, using receive is the correct approach. If the keys are not dynamic, also consider writing @Serializable data class for this request, instead of deserialising it to Map.