Ktor 3.0.2 Help

Receiving responses

All functions used to make an HTTP request (request, get, post, etc.) allow you to receive a response as an HttpResponse object. HttpResponse exposes the API required to get a response body in various ways (raw bytes, JSON objects, etc.) and obtain response parameters, such as a status code, content type, headers, and so on. For example, you can receive HttpResponse for a GET request without parameters as follows:

val response: HttpResponse = client.get("https://ktor.io/docs/welcome.html")

Receive response parameters

The HttpResponse class allows you to get various response parameters, such as a status code, headers, HTTP version, and so on.

Status code

To get the status code of a response, use the HttpResponse.status property, for example:

import io.ktor.client.* import io.ktor.client.call.* import io.ktor.client.request.* import io.ktor.http.* val httpResponse: HttpResponse = client.get("https://ktor.io/") if (httpResponse.status.value in 200..299) { println("Successful response!") }

Headers

The HttpResponse.headers property allows you to get a Headers map containing all response headers. HttpResponse also exposes a bunch of specific functions for receiving specific header values, for example:

  • contentType for the Content-Type header value

  • charset for a charset from the Content-Type header value.

  • etag for the E-Tag header value.

  • setCookie for the Set-Cookie header value.

Receive response body

Raw body

To receive a raw body of a response, call the body function and pass the required type as a parameter. The code snippet below shows how to receive a raw body as String:

val httpResponse: HttpResponse = client.get("https://ktor.io/") val stringBody: String = httpResponse.body()

Similarly, you can get a body as ByteArray:

val httpResponse: HttpResponse = client.get("https://ktor.io/") val byteArrayBody: ByteArray = httpResponse.body()

A runnable example below shows how to get a response as a byte array and save it to a file:

val client = HttpClient() val file = File.createTempFile("files", "index") runBlocking { val httpResponse: HttpResponse = client.get("https://ktor.io/") { onDownload { bytesSentTotal, contentLength -> println("Received $bytesSentTotal bytes from $contentLength") } } val responseBody: ByteArray = httpResponse.body() file.writeBytes(responseBody) println("A file saved to ${file.path}") }

JSON object

With the ContentNegotiation plugin installed, you can deserialize JSON data into a data class when receiving responses, for example:

val customer: Customer = client.get("http://localhost:8080/customer/3").body()

To learn more, see Receive and send data.

Note: there are ContentNegotiation plugins for both client and server, make sure to use proper one (client in this case).

Streaming data

When you call the HttpResponse.body function to get a body, Ktor processes a response in memory and returns a full response body. If you need to get chunks of a response sequentially instead of waiting for the entire response, use HttpStatement with scoped execute block. A runnable example below shows how to receive a response content in chunks (byte packets) and save them in a file:

val client = HttpClient(CIO) val file = File.createTempFile("files", "index") runBlocking { client.prepareGet("https://ktor.io/").execute { httpResponse -> val channel: ByteReadChannel = httpResponse.body() while (!channel.isClosedForRead) { val packet = channel.readRemaining(DEFAULT_BUFFER_SIZE.toLong()) while (!packet.isEmpty) { val bytes = packet.readBytes() file.appendBytes(bytes) println("Received ${file.length()} bytes from ${httpResponse.contentLength()}") } } println("A file saved to ${file.path}") } }

In this example, ByteReadChannel is used to read data asynchronously using byte packets (ByteReadPacket) and append the content of these packets to the content of a file.

Last modified: 02 April 2024