Ktor 2.1.1 Help

Handling requests

Ktor allows you to handle incoming requests and send responses inside route handlers. You can perform various actions when handling requests:

General request information

Inside a route handler, you can get access to a request using the call.request property. This returns the ApplicationRequest instance and provides access to various request parameters. For example, the code snippet below shows how get a request URI:

routing { get("/") { val uri = call.request.uri call.respondText("Request uri: $uri") } }

The ApplicationRequest object allows you to get access to various request data, for example:

  • Headers

    To access all request headers, use the ApplicationRequest.headers property. You can also get access to specific headers using dedicated extension functions, such as acceptEncoding, contentType, cacheControl, and so on.

  • Cookies

    The ApplicationRequest.cookies property provides access to cookies related to a request. To learn how to handle sessions using cookies, see the Sessions section.

  • Connection details

    Use the ApplicationRequest.local property to get access to connection details such as a host name, port, scheme, and so on.

  • X-Forwarded- headers

    To get information about a request passed through an HTTP proxy or a load balancer, install the Forwarded headers plugin and use the ApplicationRequest.origin property.

Path parameters

When handling requests, you can get access to path parameter values using the call.parameters property. For example, call.parameters["login"] in the code snippet below will return admin for the /user/admin path:

get("/user/{login}") { if (call.parameters["login"] == "admin") { // ... } }

Query parameters

To get access to parameters of a query string, you can use the ApplicationRequest.queryParameters property. For example, if a request is made to /products?price=asc, you can access the price query parameter in this way:

get("/products") { if (call.request.queryParameters["price"] == "asc") { // Show products from the lowest price to the highest } }

You can also obtain the entire query string using the ApplicationRequest.queryString function.

Body contents

This section shows how to receive body contents sent with POST, PUT, or PATCH.

Raw payload

To access the raw body payload and parse it by yourself, you can use the following functions:

Suppose you have the following HTTP request:

POST http://localhost:8080/text Content-Type: text/plain Hello, world!

To receive the body of this request as a String value, use ApplicationCall.receiveText:

post("/text") { val text = call.receiveText() call.respondText(text) }

You can also use ApplicationCall.receiveChannel to receive ByteReadChannel that allows asynchronous reading of byte sequences:

post("/channel") { val readChannel = call.receiveChannel() val text = readChannel.readRemaining().readText() call.respondText(text) }

You can find the full example here: post-raw-data.


Ktor provides a ContentNegotiation plugin to negotiate the media type of request and deserialize content to an object of a required type. To receive and convert content for a request, call the ApplicationCall.receive function that accepts a data class as a parameter:

post("/customer") { val customer = call.receive<Customer>() customerStorage.add(customer) call.respondText("Customer stored correctly", status = HttpStatusCode.Created) }

You can learn more from Content negotiation and serialization.

Form parameters

Ktor allows you to receive form parameters sent with both x-www-form-urlencoded and multipart/form-data types using the receiveParameters function. The example below shows an HTTP client POST request with form parameters passed in a body:

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

You can obtain parameter values in code as follows:

post("/signup") { val formParameters = call.receiveParameters() val username = formParameters["username"].toString() call.respondText("The '$username' account is created") }

You can find the full example here: post-form-parameters.

Multipart form data

If you need to receive a file sent as a part of a multipart request, call the receiveMultipart function and then loop over each part as required. In the example below, PartData.FileItem is used to receive a file as a byte stream.

import io.ktor.server.application.* import io.ktor.http.content.* import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* import java.io.File fun Application.main() { routing { var fileDescription = "" var fileName = "" post("/upload") { val multipartData = call.receiveMultipart() multipartData.forEachPart { part -> when (part) { is PartData.FormItem -> { fileDescription = part.value } is PartData.FileItem -> { fileName = part.originalFileName as String var fileBytes = part.streamProvider().readBytes() File("uploads/$fileName").writeBytes(fileBytes) } else -> {} } } call.respondText("$fileDescription is uploaded to 'uploads/$fileName'") } } }

Learn how to run this sample from upload-file.

To determine the uploaded file size, you can get the Content-Length header value inside the post handler:

post("/upload") { val contentLength = call.request.header(HttpHeaders.ContentLength) // ... }
Last modified: 16 September 2022