0
# Application and Lifecycle Management
1
2
Core application structure, configuration, lifecycle management, and the comprehensive plugin system. This includes the main Application class, pipeline processing, environment setup, and extensible plugin architecture.
3
4
## Capabilities
5
6
### Application Class
7
8
The main application class representing a configured and running web application.
9
10
```kotlin { .api }
11
/**
12
* Represents a Ktor application instance
13
*/
14
class Application internal constructor(
15
environment: ApplicationEnvironment,
16
developmentMode: Boolean,
17
var rootPath: String,
18
val monitor: Events,
19
val parentCoroutineContext: CoroutineContext,
20
private val engineProvider: () -> ApplicationEngine
21
) : ApplicationCallPipeline(developmentMode, environment), CoroutineScope {
22
/** The application engine running this application */
23
val engine: ApplicationEngine
24
/** Dispose the application and wait for completion */
25
suspend fun disposeAndJoin()
26
}
27
28
/** Extension property to get application logger */
29
val Application.log: Logger
30
```
31
32
### Application Call and Pipeline
33
34
Core interfaces for handling individual HTTP requests through pipeline processing.
35
36
```kotlin { .api }
37
/**
38
* Represents a single act of communication between client and server
39
*/
40
interface ApplicationCall : CoroutineScope {
41
/** Attributes associated with this call */
42
val attributes: Attributes
43
/** The incoming request */
44
val request: ApplicationRequest
45
/** The outgoing response */
46
val response: ApplicationResponse
47
/** The application handling this call */
48
val application: Application
49
/** Parameters associated with this call */
50
val parameters: Parameters
51
52
/** Receive request body with type information */
53
suspend fun <T> receiveNullable(typeInfo: TypeInfo): T?
54
/** Send response with type information */
55
suspend fun respond(message: Any?, typeInfo: TypeInfo?)
56
}
57
58
/**
59
* Extended ApplicationCall interface with pipeline-specific functionality
60
*/
61
interface PipelineCall : ApplicationCall
62
63
/**
64
* Pipeline configuration for executing PipelineCall instances
65
*/
66
open class ApplicationCallPipeline : Pipeline<Unit, PipelineCall> {
67
/** Pipeline for receiving request content */
68
val receivePipeline: ApplicationReceivePipeline
69
/** Pipeline for sending response content */
70
val sendPipeline: ApplicationSendPipeline
71
72
companion object {
73
/** Phase for call setup and preparation */
74
val Setup: PipelinePhase
75
/** Phase for monitoring and logging */
76
val Monitoring: PipelinePhase
77
/** Phase for plugin processing */
78
val Plugins: PipelinePhase
79
/** Phase for actual call handling */
80
val Call: PipelinePhase
81
/** Phase for fallback handling */
82
val Fallback: PipelinePhase
83
}
84
}
85
```
86
87
### Server Configuration
88
89
Configuration classes for server setup and lifecycle management.
90
91
```kotlin { .api }
92
/**
93
* Core configuration for a running server
94
*/
95
class ServerConfig {
96
/** Application environment configuration */
97
val environment: ApplicationEnvironment
98
/** Root path for the application */
99
val rootPath: String
100
/** Whether development mode is enabled */
101
val developmentMode: Boolean
102
/** Parent coroutine context */
103
val parentCoroutineContext: CoroutineContext
104
}
105
106
/**
107
* Builder for ServerConfig instances
108
*/
109
class ServerConfigBuilder {
110
/** Configure application modules */
111
fun module(body: suspend Application.() -> Unit)
112
/** Paths to watch for auto-reload in development */
113
var watchPaths: List<String>
114
/** Root path for the application */
115
var rootPath: String
116
/** Enable development mode features */
117
var developmentMode: Boolean
118
}
119
120
/**
121
* Create a ServerConfig instance
122
*/
123
fun serverConfig(block: ServerConfigBuilder.() -> Unit): ServerConfig
124
```
125
126
### Application Environment
127
128
Environment interface representing the context in which an Application runs.
129
130
```kotlin { .api }
131
/**
132
* Represents environment in which Application runs
133
*/
134
interface ApplicationEnvironment {
135
/** Logger instance for the application */
136
val log: Logger
137
/** Application configuration */
138
val config: ApplicationConfig
139
}
140
141
/**
142
* Common implementation of ApplicationEnvironment
143
*/
144
expect class CommonApplicationEnvironment : ApplicationEnvironment
145
```
146
147
### Plugin System
148
149
Comprehensive plugin architecture for extending Ktor functionality.
150
151
#### Plugin Interfaces
152
153
```kotlin { .api }
154
/**
155
* Base interface for all plugins
156
*/
157
interface Plugin<TPipeline, TConfiguration, TPlugin> {
158
/** Unique key identifying this plugin */
159
val key: AttributeKey<TPlugin>
160
/** Install the plugin into a pipeline */
161
fun install(pipeline: TPipeline, configure: TConfiguration.() -> Unit = {}): TPlugin
162
}
163
164
/**
165
* Plugin that can be installed into Application
166
*/
167
interface ApplicationPlugin<TConfiguration> : BaseApplicationPlugin<Application, TConfiguration, PluginInstance>
168
169
/**
170
* Plugin that can be installed into RoutingNode
171
*/
172
interface RouteScopedPlugin<TConfiguration> : Plugin<RoutingNode, TConfiguration, PluginInstance>
173
174
/**
175
* Instance of a plugin installed to an application
176
*/
177
class PluginInstance
178
```
179
180
#### Plugin Builders
181
182
```kotlin { .api }
183
/**
184
* Utility class to build ApplicationPlugin instances
185
*/
186
abstract class PluginBuilder<PluginConfig> {
187
/** Register handler for call processing */
188
fun onCall(block: suspend OnCallContext<PluginConfig>.(call: PipelineCall) -> Unit)
189
/** Register handler for call receive events */
190
fun onCallReceive(block: suspend OnCallReceiveContext<PluginConfig>.(call: PipelineCall, body: Any) -> Unit)
191
/** Register handler for call respond events */
192
fun onCallRespond(block: suspend OnCallRespondContext<PluginConfig>.(call: PipelineCall, body: Any) -> Unit)
193
/** Register hook handler */
194
fun <HookHandler> on(hook: Hook<HookHandler>, handler: HookHandler)
195
}
196
197
/**
198
* Builder for RouteScopedPlugin instances
199
*/
200
abstract class RouteScopedPluginBuilder<PluginConfig> : PluginBuilder<PluginConfig>() {
201
/** The route this plugin is scoped to */
202
val route: RoutingNode?
203
}
204
```
205
206
#### Plugin Creation Functions
207
208
```kotlin { .api }
209
/**
210
* Create an ApplicationPlugin with no configuration
211
*/
212
fun createApplicationPlugin(
213
name: String,
214
body: PluginBuilder<Unit>.() -> Unit
215
): ApplicationPlugin<Unit>
216
217
/**
218
* Create an ApplicationPlugin with custom configuration
219
*/
220
fun <PluginConfigT> createApplicationPlugin(
221
name: String,
222
createConfiguration: () -> PluginConfigT,
223
body: PluginBuilder<PluginConfigT>.() -> Unit
224
): ApplicationPlugin<PluginConfigT>
225
226
/**
227
* Create a RouteScopedPlugin with no configuration
228
*/
229
fun createRouteScopedPlugin(
230
name: String,
231
body: RouteScopedPluginBuilder<Unit>.() -> Unit
232
): RouteScopedPlugin<Unit>
233
234
/**
235
* Create a RouteScopedPlugin with custom configuration
236
*/
237
fun <PluginConfigT> createRouteScopedPlugin(
238
name: String,
239
createConfiguration: () -> PluginConfigT,
240
body: RouteScopedPluginBuilder<PluginConfigT>.() -> Unit
241
): RouteScopedPlugin<PluginConfigT>
242
```
243
244
#### Plugin Installation and Access
245
246
```kotlin { .api }
247
/**
248
* Install a plugin into an application
249
*/
250
fun <TConfiguration> Application.install(
251
plugin: ApplicationPlugin<TConfiguration>,
252
configure: TConfiguration.() -> Unit = {}
253
): PluginInstance
254
255
/**
256
* Install a plugin into a route
257
*/
258
fun <TConfiguration> Route.install(
259
plugin: RouteScopedPlugin<TConfiguration>,
260
configure: TConfiguration.() -> Unit = {}
261
): PluginInstance
262
263
/**
264
* Get a plugin instance, throws if not installed
265
*/
266
fun <TConfiguration> Application.plugin(plugin: ApplicationPlugin<TConfiguration>): PluginInstance
267
268
/**
269
* Get a plugin instance or null if not installed
270
*/
271
fun <TConfiguration> Application.pluginOrNull(plugin: ApplicationPlugin<TConfiguration>): PluginInstance?
272
```
273
274
### Hook System
275
276
Event-driven hooks for plugin integration and lifecycle management.
277
278
```kotlin { .api }
279
/**
280
* Hook that can be registered in PluginBuilder
281
*/
282
interface Hook<HookHandler> {
283
/** Install the hook into a pipeline */
284
fun install(pipeline: ApplicationCallPipeline, handler: HookHandler)
285
}
286
287
/**
288
* Hook invoked as first step in processing a call
289
*/
290
object CallSetup : Hook<suspend (PipelineCall) -> Unit>
291
292
/**
293
* Hook invoked when call fails with exception
294
*/
295
object CallFailed : Hook<suspend (PipelineCall, Throwable) -> Unit>
296
297
/**
298
* Hook for when response body is ready to be sent
299
*/
300
object ResponseBodyReadyForSend : Hook<suspend (PipelineCall) -> Unit>
301
302
/**
303
* Hook for when response was successfully sent
304
*/
305
object ResponseSent : Hook<suspend (PipelineCall) -> Unit>
306
307
/**
308
* Shortcut hook for Application.monitor subscription
309
*/
310
class MonitoringEvent<T>(val definition: EventDefinition<T>) : Hook<suspend (T) -> Unit>
311
```
312
313
### Module Configuration
314
315
Application module management and startup configuration.
316
317
```kotlin { .api }
318
/**
319
* Application startup mode for modules
320
*/
321
enum class ApplicationStartupMode {
322
SEQUENTIAL,
323
CONCURRENT
324
}
325
```
326
327
### Extension Properties
328
329
Useful extension properties for Application and ApplicationConfig.
330
331
```kotlin { .api }
332
/** Get application logger */
333
val Application.log: Logger
334
335
/** Get host configuration from ApplicationConfig */
336
val ApplicationConfig.host: String
337
338
/** Get port configuration from ApplicationConfig */
339
val ApplicationConfig.port: Int
340
```
341
342
### Exception Classes
343
344
Exceptions related to plugin management and application lifecycle.
345
346
```kotlin { .api }
347
/**
348
* Thrown when plugin with same key is already installed
349
*/
350
class DuplicatePluginException(message: String) : Exception(message)
351
352
/**
353
* Thrown when accessing plugin that is not installed
354
*/
355
class MissingApplicationPluginException(key: AttributeKey<*>) : IllegalStateException()
356
```
357
358
## Usage Examples
359
360
### Basic Application Setup
361
362
```kotlin
363
import io.ktor.server.application.*
364
import io.ktor.server.engine.*
365
366
fun main() {
367
val config = serverConfig {
368
developmentMode = true
369
rootPath = "/api"
370
module {
371
// Configure application
372
configureRouting()
373
configurePlugins()
374
}
375
}
376
377
embeddedServer(Netty, rootConfig = config) {
378
// Additional engine configuration
379
}.start(wait = true)
380
}
381
382
fun Application.configurePlugins() {
383
install(CallLogging) {
384
level = Level.INFO
385
}
386
}
387
```
388
389
### Custom Plugin Creation
390
391
```kotlin
392
import io.ktor.server.application.*
393
394
// Simple plugin with no configuration
395
val SimpleLoggingPlugin = createApplicationPlugin("SimpleLogging") {
396
onCall { call ->
397
println("Processing request: ${call.request.uri}")
398
}
399
}
400
401
// Plugin with configuration
402
data class TimingConfig(var enabled: Boolean = true)
403
404
val RequestTimingPlugin = createApplicationPlugin(
405
name = "RequestTiming",
406
createConfiguration = ::TimingConfig
407
) {
408
val enabled = pluginConfig.enabled
409
410
if (enabled) {
411
onCall { call ->
412
val start = System.currentTimeMillis()
413
call.attributes.put(StartTimeKey, start)
414
}
415
416
on(ResponseSent) { call ->
417
val start = call.attributes[StartTimeKey]
418
val duration = System.currentTimeMillis() - start
419
println("Request completed in ${duration}ms")
420
}
421
}
422
}
423
424
private val StartTimeKey = AttributeKey<Long>("StartTime")
425
426
// Install and use the plugins
427
fun Application.configurePlugins() {
428
install(SimpleLoggingPlugin)
429
install(RequestTimingPlugin) {
430
enabled = environment.developmentMode
431
}
432
}
433
```
434
435
### Route-Scoped Plugin
436
437
```kotlin
438
val RateLimitPlugin = createRouteScopedPlugin("RateLimit") {
439
val route = route ?: return@createRouteScopedPlugin
440
441
onCall { call ->
442
val clientIp = call.request.origin.remoteHost
443
if (isRateLimited(clientIp)) {
444
call.respond(HttpStatusCode.TooManyRequests)
445
return@onCall
446
}
447
recordRequest(clientIp)
448
}
449
}
450
451
fun Route.configureRateLimit() {
452
install(RateLimitPlugin)
453
}
454
```