I am using Ktor 3.x and am looking to start an embedded server using the Coroutine scope extension function, while also supplying my own configure script.
The documentation I am referencing is here.
As we can see from the function signature, there exists one which allows you to pass your own configure: TConfiguration.() -> Unit = {}
.
fun <TEngine : ApplicationEngine, TConfiguration : ApplicationEngine.Configuration> embeddedServer(
factory: ApplicationEngineFactory<TEngine, TConfiguration>,
environment: ApplicationEnvironment = applicationEnvironment(),
configure: TConfiguration.() -> Unit = {},
module: Application.() -> Unit = {}
): EmbeddedServer<TEngine, TConfiguration>
Observing the extension functions from CoroutineScope
, they do not allow us to pass a configure
block:
fun <TEngine : ApplicationEngine, TConfiguration : ApplicationEngine.Configuration> CoroutineScope.embeddedServer(
factory: ApplicationEngineFactory<TEngine, TConfiguration>,
vararg connectors: EngineConnectorConfig = arrayOf(),
watchPaths: List<String> = listOf(WORKING_DIRECTORY_PATH),
parentCoroutineContext: CoroutineContext = EmptyCoroutineContext,
module: Application.() -> Unit
): EmbeddedServer<TEngine, TConfiguration>
&
fun <TEngine : ApplicationEngine, TConfiguration : ApplicationEngine.Configuration> CoroutineScope.embeddedServer(
factory: ApplicationEngineFactory<TEngine, TConfiguration>,
port: Int = 80,
host: String = "0.0.0.0",
watchPaths: List<String> = listOf(WORKING_DIRECTORY_PATH),
parentCoroutineContext: CoroutineContext = EmptyCoroutineContext,
module: Application.() -> Unit
): EmbeddedServer<TEngine, TConfiguration>
What is the expected way to gain the configure
functionality when working with the extension function?
Unfortunately, there is no way to configure the engine while using the CoroutineScope.embeddedServer
method. However, you can define your own overloaded method, which would allow that:
fun <TEngine : ApplicationEngine, TConfiguration : ApplicationEngine.Configuration> CoroutineScope.embeddedServer(
factory: ApplicationEngineFactory<TEngine, TConfiguration>,
environment: ApplicationEnvironment = applicationEnvironment(),
configure: TConfiguration.() -> Unit = {},
module: Application.() -> Unit = {}
): EmbeddedServer<TEngine, TConfiguration> {
val applicationProperties = serverConfig(environment) {
this.parentCoroutineContext = coroutineContext + parentCoroutineContext
this.module(module)
}
return embeddedServer(factory, applicationProperties, configure)
}
Here is an example of the method usage:
CoroutineScope(Dispatchers.IO).embeddedServer(
Netty,
applicationEnvironment {},
configure = {
maxHeaderSize = 1024 * 1024
connectors.add(EngineConnectorBuilder().withPort(8833))
}
) {
routing {
get {
call.respondText("Hello World!")
}
}
}.start(wait = true)