Ktor: JSON data in POST

Hello, I’m trying to make a POST request with headers and data.

    inline fun <reified T> post(url: String, headersMap: Map<String, String>, data: String) = runBlocking {
        return@runBlocking httpClient.post<T>(url) {
            headers {
                headersMap.forEach { append(it.key, it.value) }
            }
            body = TextContent(
                text = data,
                contentType = ContentType.Application.Json
            )
        }
    }

I think, there could be future optimizations with runBlocking and headersMap.forEach but currently I’m not sure if all is ok with sending request data here. My data is a JSON-like String but maybe it’s not the valid way to make it this way: data = "{\"page\":$page, \"page_size\": $pageSize}"

Anyway, I got a response like body data was not used. What is the correct method to send the data in Ktor?

The Python method:

requests.post(url, headers=request_data, data=json.dumps(request_json)).json()

where request_data is a dictionary

The curl method looks like this:

curl 'https://www.url/' \
  -H 'Content-Type: application/json' \
  -H 'Referer: https://url/' \
  --data-raw "{"page":2, "page_size":50}" \
  --compressed

P.S. With this structure I got Serializer for class 'TextContent' is not found. SerializationException

Try something like ths:

    val content = client.post<HttpResponse> {
      body = data
      contentType(ContentType.Application.Json)
      url(httpUrl)
      for (element in headersMap) {
        headers[element.key] = element.value
      }
    }
    .readText()

With this I get an Error 500. Looks like something is wrong with the body data but I checked same string in Python and all is ok there.

Use some proxy to see what exactly do you send. Or if you are on linux, just run nc -lp 8080 and point your client at it. Compare results from Python and Ktor.

1 Like

Error 500 - Internal Server Error. Your request reached the server.

Yeah, I’m trying to configure Fiddler Linux or install Ktor logging. With the second way I got this:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

Need some time to fix.

I found the data is sent as a String in Ktor while all is a plain JSON with curl or Python. But not sure how should I send JSON properly.

Update: all looks ok with JsonElement from Json.parseToJsonElement(data)