Sending responses
Ktor allows you to handle incoming requests and send responses inside route handlers. You can send different types of responses: plain text, HTML documents and templates, serialized data objects, and so on. You can also configure various response parameters, such as content type, headers, cookies, and the status code.
Inside a route handler, the following API is available for working with responses:
A set of functions for sending specific content types, such as
call.respondText()andcall.respondHtml().The
call.respond()function that allows you to send any data type inside a response. When the ContentNegotiation plugin is installed, you can send a data object serialized in a specific format.The
call.response()property that returns theApplicationResponseobject, providing access to response parameters for setting the status code, adding headers, and configuring cookies.The
call.respondRedirect()function for sending redirect responses.
Set response payload
Plain text
To send plain text, use the call.respondText() function:
HTML
Ktor provides two main mechanisms for generating HTML responses:
Building HTML using the Kotlin HTML DSL.
Rendering templates using JVM template engines such as FreeMarker or Velocity.
Full HTML documents
To send full HTML documents built with Kotlin DSL, use the call.respondHtml() function:
Partial HTML fragments
If you need to return only a fragment of HTML, without wrapping it in <html>, <head>, or <body>, you can use call.respondHtmlFragment():
Templates
To send a template in a response, use the call.respond() function with a specific content:
You can also use the call.respondTemplate() function:
You can learn more from the Templating help section.
Object
To enable serialization of data objects in Ktor, you need to install the ContentNegotiation plugin and register a required converter (for example, JSON). Then, you can use the call.respond() function to pass a data object in a response:
For the full example, see json-kotlinx.
File
To respond to a client with the content of a file, you have two options:
For a file represented as a
Fileobject, use thecall.respondFile()function.For a file pointed by the given
Pathobject, use thecall.respond()function with theLocalPathContentclass.
The example below shows how to send a file and make it downloadable by adding the Content-Disposition header:
Note that this sample uses two plugins:
PartialContentenables the server to respond to requests with theRangeheader and send only a portion of content.AutoHeadResponseprovides the ability to automatically respond to aHEADrequest for every route that has aGETdefined. This allows the client application to determine the file size by reading theContent-Lengthheader value.
For the full code sample, see download-file.
Resource
You can serve a single resource from the classpath with the call.respondResource() method. This method accepts the path to the resource and sends a response constructed in the following way: it reads the response body from the resource stream, and derives the Content-Type header from the file extension.
The following example shows the method call in a route handler:
In the example above, since the resource extension is .html, the response will include the Content-Type: text/html header. For convenience, you can pass components of the resource location, namely relative path and package, separately through the first and second parameters. The following example resolves resources under the assets package based on the requested path:
If the requested path after the /assets prefix is empty or /, the handler uses the default index.html resource to respond. If no resource is found at the given path, IllegalArgumentException is thrown. The previous code snippet mimics a more general solution — serving resources from a package with the staticResources() method.
Raw payload
To send the raw body payload, use the call.respondBytes() function.
Set response parameters
Status code
To set a status code for a response, call the ApplicationResponse.status() function with a predefined status code value:
You can also specify custom status values:
Content type
With the ContentNegotiation plugin installed, Ktor chooses a content type automatically. If required, you can specify a content type manually by passing a corresponding parameter.
In the example below, the call.respondText() function accepts ContentType.Text.Plain as a parameter:
Headers
You can add headers to a response in several ways:
Modify the
ApplicationResponse.headerscollection:get("/") { call.response.headers.append(HttpHeaders.ETag, "7c876b7e") // For multiple values for the same header call.response.headers.appendAll("X-Custom-Header" to listOf("value1", "value2")) }Use the
ApplicationResponse.header()function:get("/") { call.response.header(HttpHeaders.ETag, "7c876b7e") }Use convenience functions for specific headers, such as
ApplicationResponse.etag,ApplicationResponse.link, and others.get("/") { call.response.etag("7c876b7e") }Add custom headers by passing raw string names:
get("/") { call.response.header("Custom-Header", "Some value") }
Cookies
To configure cookies sent in a response, use the ApplicationResponse.cookies property:
Redirects
To generate a redirect response, use the call.respondRedirect() function: