Ktor 3.0.3 Help

Configuration in code

Ktor allows you to configure various server parameters directly in code, including the host address, port, server modules, and more. The method of configuration depends on the way you set up a server - using embeddedServer or EngineMain.

With embeddedServer, you configure the server by passing the desired parameters directly to the function. The embeddedServer function accepts different parameters for configuring a server, including a server engine, the host and port for the server to listen on, and additional configurations.

In this section, we'll take a look at several different examples of running embeddedServer, illustrating how you can configure the server to your advantage.

Basic configuration

The code snippet below shows a basic server setup with the Netty engine and the 8080 port.

import io.ktor.server.response.* import io.ktor.server.routing.* import io.ktor.server.engine.* import io.ktor.server.netty.* fun main(args: Array<String>) { embeddedServer(Netty, port = 8080) { routing { get("/") { call.respondText("Hello, world!") } } }.start(wait = true) }

Note that you can set the port parameter to 0 to run the server on a random port. The embeddedServer function returns an engine instance, so you can get a port value in code using the ApplicationEngine.resolvedConnectors function.

Engine configuration

The embeddedServer function allows you to pass engine-specific options using the configure parameter. This parameter includes options common for all engines and exposed by the ApplicationEngine.Configuration class.

The example below shows how to configure a server using the Netty engine. Within the configure block, we define a connector to specify the host and port, and customize various server parameters:

import io.ktor.server.response.* import io.ktor.server.routing.* import io.ktor.server.engine.* import io.ktor.server.netty.* fun main(args: Array<String>) { embeddedServer(Netty, configure = { connectors.add(EngineConnectorBuilder().apply { host = "127.0.0.1" port = 8080 }) connectionGroupSize = 2 workerGroupSize = 5 callGroupSize = 10 shutdownGracePeriod = 2000 shutdownTimeout = 3000 }) { routing { get("/") { call.respondText("Hello, world!") } } }.start(wait = true) }

The connectors.add() method defines a connector with the specified host (127.0.0.1) and port (8080).

In addition to these options, you can configure other engine-specific properties.

Netty

Netty-specific options are exposed by the NettyApplicationEngine.Configuration class.

import io.ktor.server.engine.* import io.ktor.server.netty.* fun main() { embeddedServer(Netty, configure = { requestQueueLimit = 16 shareWorkGroup = false configureBootstrap = { // ... } responseWriteTimeoutSeconds = 10 }) { // ... }.start(true) }

Jetty

Jetty-specific options are exposed by the JettyApplicationEngineBase.Configuration class.

You can configure the Jetty server inside the configureServer block, which provides access to a Server instance.

Use the idleTimeout property to specify the duration of time a connection can be idle before it gets closed.

import io.ktor.server.engine.* import io.ktor.server.jetty.* fun main() { embeddedServer(Jetty, configure = { configureServer = { // this: Server -&gt; // ... } idleTimeout = 30.seconds }) { // ... }.start(true) }

CIO

CIO-specific options are exposed by the CIOApplicationEngine.Configuration class.

import io.ktor.server.engine.* import io.ktor.server.cio.* fun main() { embeddedServer(CIO, configure = { connectionIdleTimeoutSeconds = 45 }) { // ... }.start(true) }

Tomcat

If you use Tomcat as the engine, you can configure it using the configureTomcat property, which provides access to a Tomcat instance.

import io.ktor.server.engine.* import io.ktor.server.tomcat.* fun main() { embeddedServer(Tomcat, configure = { configureTomcat = { // this: Tomcat -&gt; // ... } }) { // ... }.start(true) }

Custom environment

The example below shows how to run a server with multiple connector endpoints using a custom configuration represented by the ApplicationEngine interface.

import io.ktor.server.application.* import io.ktor.server.response.* import io.ktor.server.routing.* import io.ktor.server.engine.* import io.ktor.server.netty.* fun main() { val appProperties = serverConfig { module { module() } } embeddedServer(Netty, appProperties) { envConfig() }.start(true) } fun ApplicationEngine.Configuration.envConfig() { connector { host = "0.0.0.0" port = 8080 } connector { host = "127.0.0.1" port = 9090 } }

For the complete example, see embedded-server-multiple-connectors.

Command-line configuration

Ktor allows you to dynamically configure an embeddedServer using command-line arguments. This can be particularly useful in cases where configurations like ports, hosts, or timeouts need to be specified at runtime.

To achieve this, use the CommandLineConfig class to parse command-line arguments into a configuration object and pass it within the configuration block:

fun main(args: Array<String>) { embeddedServer( factory = Netty, configure = { val cliConfig = CommandLineConfig(args) takeFrom(cliConfig.engineConfig) loadCommonConfiguration(cliConfig.rootConfig.environment.config) } ) { routing { get("/") { call.respondText("Hello, world!") } } }.start(wait = true) }

In this example, the takeFrom() function from Application.Configuration is used to override engine configuration values, such as port and host. The loadCommonConfiguration() function loads configuration from the root environment, such as timeouts.

To run the server, specify arguments in the following way:

./gradlew run --args="-port=8080"
Last modified: 16 December 2024