Handling requests
Ktor allows you to handle incoming requests and send responses from route handlers.
Each route handler provides an ApplicationCall through the call property. An ApplicationCall represents a single HTTP exchange and provides access to both the incoming request and the outgoing response.
Within a route handler, you can use ApplicationCall to perform the following:
Access request information, such as headers, cookies, and connection details.
Retrieve path parameters.
Retrieve query parameters.
Receive request body content, such as data objects, form parameters, and files.
General request information
You can access request data through the call.request property. This returns an ApplicationRequest instance, which provides access to low-level HTTP request information.
For example, you can retrieve the request URI in a GET request handler using call.request.uri:
The call.respondText() function sends a plain text response back to the client.
Headers
To access all HTTP request headers, use the ApplicationRequest.headers property.
For convenience, Ktor also provides dedicated extension functions for accessing commonly used headers, such as .acceptEncoding(), .contentType(), and .cacheControl().
Cookies
To access cookies sent with the request, use the ApplicationRequest.cookies property.
Connection details
Use the ApplicationRequest.local property to access connection details such as the host, port, and scheme.
X-Forwarded- headers
To collect information about a request passed through an HTTP proxy or a load balancer, install the Forwarded headers plugin. You can then access this information through the ApplicationRequest.origin property.
Path parameters
When handling requests, you can retrieve path parameter values using the ApplicationCall.parameters property.
For example, call.parameters["login"] returns "admin" for a request to /user/admin:
Query parameters
To retrieve parameters of a URL query string, use the ApplicationRequest.queryParameters property.
The following example accesses the price query parameter from a request made to /products?price=asc:
You can also get the entire query string using the ApplicationRequest.queryString() function.
Required request parameters
When handling requests, it is common to extract values from path parameters, query parameters, headers, or cookies and validate that they are present before continuing request processing.
Instead of manually checking for missing values in every route handler, Ktor provides the following helper functions that simplify accessing required request data:
.requireQueryParameter()retrieves a required query parameter from the request URL..requireHeader()retrieves a required HTTP header value..requireCookie()retrieves a required cookie value, optionally decoding it using the specified encoding..requirePathParameter()retrieves a required path parameter from the route definition.
Each function returns a non-null value or throws MissingRequestParameterException if the requested value is missing.
Body contents
To access the request body, use Ktor's receive functions. The appropriate function depends on whether you need raw content, a deserialized object, form parameters, or multipart data.
Raw payload
To access the raw body payload and parse it manually, use the ApplicationCall.receive() function that accepts a type of payload to be received.
Suppose a client sends the following HTTP request:
You can receive the request body as a String, ByteArray, or ByteReadChannel.
String
To receive a request body as text, use the .receive<String>() or .receiveText() function:
ByteArray
To receive the body of a request as a byte array, use the .receive<ByteArray>() function:
ByteReadChannel
To read the body asynchronously as a ByteReadChannel, use the .receive<ByteReadChannel>() or .receiveChannel() function:
You can also use a ByteReadChannel to upload a file:
Objects
Ktor provides the 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, use the ApplicationCall.receive() function with the expected type:
If the request content can deserialize to null, use a nullable type argument:
Form parameters
You can receive form parameters sent with both x-www-form-urlencoded and multipart/form-data types using the .receiveParameters() function.
For example, suppose a client sends the following request:
You can access parameter values in code as follows:
Multipart form data
To receive a file sent as a part of a multipart request, use the .receiveMultipart() function.
Multipart request data is processed sequentially, so you can't directly access a specific part of it. Each part can represent a form field, a file, or other binary content, so handle each type separately.
The following example receives a form field and a file, then saves the file to the local file system:
Default file size limit
By default, binary and file parts are limited to 50MiB. If a part exceeds this limit, Ktor throws an IOException.
To override the default limit for a call, pass the formFieldLimit parameter to the .receiveMultipart() function:
This example sets the limit to 100 MiB.
Form fields
PartData.FormItem represents a form field. You can access its value through the value property:
File uploads
PartData.FileItem represents an uploaded file. You can handle file uploads as byte streams. Use the .provider() function to access the file content as a ByteReadChannel and stream it to a destination:
With the .copyAndClose() function, you write the file content to the specified destination while ensuring proper resource cleanup.
If the request includes a Content-Length header value, you can use it to inspect the size of the complete request body:
For multipart requests, Content-Length represents the entire multipart body, not the size of an individual uploaded file.
Resource cleanup
Once form processing is complete, dispose of each multipart part using the .dispose() function to free its resources: