Core
Application lifecycle, type-safe routing, CLI framework, fixtures, configuration, and repair system.
App lifecycle
Funktor provides hooks for every stage of the application lifecycle. Implement the hook interface, register it in Kontainer, and it runs automatically.
class MyStartupHook : AppLifeCycleHooks.OnAppStarted {
override val executionOrder = ExecutionOrder.Normal
override suspend fun onAppStarted(application: Application) {
// Run after the app has started
}
} Available hooks: OnAppStarting, OnAppStarted, OnAppStopPreparing,
OnAppStopping, OnAppStopped. Each supports ExecutionOrder for
priority control (ExtremelyEarly through ExtremelyLate).
Type-safe routing
Routes carry their parameter types at compile time. No stringly-typed path extraction.
data class UserParams(val id: String)
val getUserRoute = route<UserParams>("/users/{id}")
// In routing setup:
get(getUserRoute) { params ->
val user = userService.get(params.id)
call.respond(user)
} CLI framework
Register Clikt commands in
Kontainer. Run them with --cli. Built-in commands include app:info,
app:config, fixtures:install, and fixtures:list.
class MyCommand : CliktCommand(name = "my:command") {
val count by option().int().default(10)
override fun run() {
echo("Running with count=$count")
}
}
// Register in module:
val MyModule = module {
singleton(MyCommand::class)
} Fixtures
Load test data with dependency ordering. Fixtures declare what they depend on, and the installer resolves the correct execution order.
class UserFixtures(
repo: UserRepo,
private val authRecords: AuthRecordStorage,
) : RepoFixtureLoader<User>(repo = repo) {
val admin = singleFix {
repo.insert("admin", User(name = "Admin", email = "admin@example.com"))
.also { user -> authRecords.createPassword(user, "password123") }
}
override val dependsOn = listOf<FixtureLoader>()
} Configuration
Type-safe configuration via Typesafe Config. Environment-specific files
(application.dev.conf, application.prod.conf) are merged automatically.
Repair system
Register RepairMan.Repair implementations to run data migrations or fixes on startup.
Failures are logged but don't prevent the app from starting.