Skip to main content
Version: v0.13

Ktor Server Integration

The IDK provides a Ktor server plugin that integrates the three-scope architecture (App, User, Session) with Ktor's request handling. This enables dependency injection and service access within your Ktor routes.

Installation​

Add the Ktor server plugin to your dependencies:

build.gradle.kts
dependencies {
implementation("com.sphereon.oss.idk:ktor-server-kotlin-inject:0.13.0")
}

Plugin Setup​

Install the KotlinInjectPlugin in your Ktor application:

import com.sphereon.ktor.server.inject.KotlinInjectPlugin
import io.ktor.server.application.*
import io.ktor.server.cio.*
import io.ktor.server.engine.*

fun main() {
embeddedServer(CIO, port = 8080) {
configureKotlinInject()
configureRouting()
}.start(wait = true)
}

fun Application.configureKotlinInject() {
// Create your AppComponent
val appComponent = MyAppComponent.init(
application = this,
appId = "my-app",
profile = "production",
version = "1.0.0"
)

// Install the plugin
install(KotlinInjectPlugin) {
this.appComponent = appComponent
// Optional: custom tenant/principal resolvers
// tenantResolver = MyTenantResolver()
// principalResolver = MyPrincipalResolver()
}
}

Accessing Services in Routes​

Use extension functions to access services from different scopes:

import com.sphereon.ktor.server.inject.*
import io.ktor.server.routing.*
import io.ktor.server.response.*

fun Application.configureRouting() {
routing {
get("/config") {
// Access app-scoped services
val config = call.getAppService<AppConfigEnvironment>()
call.respondText("App: ${config.getAppName()}")
}

get("/user/{userId}") {
// Access user-scoped services
val userLogger = call.getUserService<UserContextLogManager>()
userLogger.withTag("API").info("User endpoint accessed")

// Access user context directly
val userInstance = call.userInstance
call.respondText("Tenant: ${userInstance.context.tenant}")
}

get("/session") {
// Access session-scoped services
val sessionLogger = call.getSessionService<SessionLogManager>()
val sessionInstance = call.sessionInstance

call.respondText("Session: ${sessionInstance.sessionId}")
}
}
}

Universal HTTP Adapters​

For API endpoints that need to work across both Ktor and Spring, use the Universal HTTP Adapter pattern. Install the adapter dispatcher to automatically route requests to registered adapters:

import com.sphereon.ktor.server.inject.installUniversalHttpAdapters

fun Application.module() {
install(KotlinInjectPlugin) {
appComponent = myAppComponent
}

// Mount adapters under /api prefix
installUniversalHttpAdapters {
pathPrefix = "/api"
verboseLogging = true
}
}

Or mount adapters within a specific route:

routing {
route("/api/v1") {
installUniversalHttpAdapters()
}
}

The dispatcher automatically converts Ktor requests to GenericHttpRequest, delegates to registered HttpAdapter implementations, and converts responses back to Ktor responses.

Platform Support​

The Ktor server plugin is multiplatform and works on:

  • JVM - Standard server deployments
  • Native - GraalVM native images for fast startup
  • JavaScript - Node.js server deployments

Next Steps​