or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application.mdconfig.mdengine.mdindex.mdrequest-response.mdrouting.mdutilities.md

application.mddocs/

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

```