Core server functionality for the Ktor asynchronous web framework, providing essential building blocks for HTTP servers including application lifecycle management, routing foundations, request/response handling, and plugin architecture specifically compiled for JVM targets.
—
URL routing system with DSL for defining routes, handling different HTTP methods, extracting path parameters, and organizing complex routing hierarchies with middleware support.
Core routing classes for building routing trees and handling HTTP requests with path matching and parameter extraction.
/**
* Represents a route in the routing tree
*/
class Route(
val parent: Route?,
val selector: RouteSelector,
val developmentMode: Boolean = false,
val environment: ApplicationEnvironment
) : ApplicationCallPipeline() {
/** Child routes */
val children: List<Route>
/** Route handlers */
val handlers: List<PipelineInterceptor<Unit, ApplicationCall>>
/** Create child route with selector */
fun createChild(selector: RouteSelector): Route
/** Install handler for this route */
fun handle(body: PipelineInterceptor<Unit, ApplicationCall>)
}
/**
* Root routing node
*/
class Routing(
private val application: Application
) : Route(parent = null, selector = RootRouteSelector, environment = application.environment)
/**
* DSL builder for constructing routing trees
*/
class RoutingBuilder : RouteDSL functions for handling different HTTP methods with path patterns and request processing.
/**
* Handle GET requests
* @param path - URL path pattern (supports parameters like {id})
* @param body - Request handler function
*/
fun Route.get(path: String, body: RoutingHandler): Route
fun Route.get(body: RoutingHandler): Route
/**
* Handle POST requests
* @param path - URL path pattern
* @param body - Request handler function
*/
fun Route.post(path: String, body: RoutingHandler): Route
fun Route.post(body: RoutingHandler): Route
/**
* Handle PUT requests
* @param path - URL path pattern
* @param body - Request handler function
*/
fun Route.put(path: String, body: RoutingHandler): Route
fun Route.put(body: RoutingHandler): Route
/**
* Handle DELETE requests
* @param path - URL path pattern
* @param body - Request handler function
*/
fun Route.delete(path: String, body: RoutingHandler): Route
fun Route.delete(body: RoutingHandler): Route
/**
* Handle PATCH requests
* @param path - URL path pattern
* @param body - Request handler function
*/
fun Route.patch(path: String, body: RoutingHandler): Route
fun Route.patch(body: RoutingHandler): Route
/**
* Handle HEAD requests
* @param path - URL path pattern
* @param body - Request handler function
*/
fun Route.head(path: String, body: RoutingHandler): Route
fun Route.head(body: RoutingHandler): Route
/**
* Handle OPTIONS requests
* @param path - URL path pattern
* @param body - Request handler function
*/
fun Route.options(path: String, body: RoutingHandler): Route
fun Route.options(body: RoutingHandler): Route
/**
* Handle requests for specific HTTP method
* @param method - HTTP method to handle
* @param path - URL path pattern
* @param body - Request handler function
*/
fun Route.method(method: HttpMethod, path: String, body: RoutingHandler): Route
fun Route.method(method: HttpMethod, body: RoutingHandler): Route
/**
* Type alias for routing handler functions
*/
typealias RoutingHandler = suspend RoutingContext.() -> Unit
/**
* Context for routing handlers
*/
class RoutingContext(
val call: RoutingCall
)Functions for creating nested routes and organizing routing hierarchies with shared middleware and path prefixes.
/**
* Create nested routes with path prefix
* @param path - Path prefix for nested routes
* @param build - Function to configure nested routes
*/
fun Route.route(path: String, build: Route.() -> Unit): Route
/**
* Install and configure routing for application
* @param configuration - Function to configure routing tree
*/
fun Application.routing(configuration: Routing.() -> Unit): Routing
/**
* Create route group without path prefix
* @param build - Function to configure route group
*/
fun Route.route(build: Route.() -> Unit): RouteClasses for matching routes based on different criteria including HTTP methods, path segments, and parameters.
/**
* Base class for route selection criteria
*/
abstract class RouteSelector {
/** Evaluate selector against current request */
abstract fun evaluate(context: RoutingResolveContext, segmentIndex: Int): RouteSelectorEvaluation
/** Build string representation */
abstract fun toString(): String
}
/**
* Selector for HTTP methods
*/
data class HttpMethodRouteSelector(val method: HttpMethod) : RouteSelector
/**
* Selector for exact path segments
*/
data class PathSegmentRouteSelector(val value: String, val optional: Boolean = false) : RouteSelector
/**
* Selector for path parameters (e.g., {id})
*/
data class ParameterRouteSelector(val name: String, val optional: Boolean = false) : RouteSelector
/**
* Selector for wildcard path segments
*/
data class WildcardRouteSelector(val name: String) : RouteSelector
/**
* Selector for trailing path segments
*/
object TailcardRouteSelector : RouteSelector
/**
* Root route selector
*/
object RootRouteSelector : RouteSelectorSystem for resolving incoming requests to appropriate route handlers with parameter extraction.
/**
* Context for route resolution
*/
class RoutingResolveContext(
val routing: Route,
val call: ApplicationCall,
val parameters: MutableMap<String, String> = mutableMapOf()
) {
/** Segments from request path */
val segments: List<String>
/** Current segment index during resolution */
var segmentIndex: Int
}
/**
* Result of route resolution
*/
sealed class RoutingResolveResult {
/** Successful route resolution */
class Success(val route: Route, val parameters: Map<String, String>) : RoutingResolveResult()
/** Route not found */
object Failure : RoutingResolveResult()
}
/**
* Evaluation result for route selector
*/
sealed class RouteSelectorEvaluation {
/** Selector matches */
object Success : RouteSelectorEvaluation()
/** Selector doesn't match */
object Failure : RouteSelectorEvaluation()
/** Selector matches with consumed segments */
class SuccessWithConsume(val segmentCount: Int) : RouteSelectorEvaluation()
}Support for middleware that applies to specific routes or route groups with proper scoping.
/**
* Install interceptor for route and all child routes
* @param phase - Pipeline phase to install interceptor
* @param block - Interceptor function
*/
fun Route.intercept(phase: PipelinePhase, block: PipelineInterceptor<Unit, ApplicationCall>)
/**
* Install route-scoped plugin
* @param plugin - Plugin to install
* @param configuration - Plugin configuration
*/
fun <TConfiguration : Any> Route.install(
plugin: RouteScopedPlugin<TConfiguration, *>,
configuration: TConfiguration.() -> Unit = {}
)Utilities for extracting and converting path parameters from matched routes.
/**
* Parameter collection for route parameters
*/
interface Parameters {
/** Get parameter value by name */
operator fun get(name: String): String?
/** Get all values for parameter name */
fun getAll(name: String): List<String>?
/** Get all parameter names */
fun names(): Set<String>
/** Check if parameter exists */
fun contains(name: String): Boolean
/** Check if parameter has specific value */
fun contains(name: String, value: String): Boolean
}
/** Access route parameters from application call */
val ApplicationCall.parameters: Parameters
/** Utility functions for parameter conversion */
fun Parameters.getOrFail(name: String): String =
get(name) ?: throw ParameterConversionException(name, "String", "Parameter $name not found")
fun Parameters.getInt(name: String): Int? = get(name)?.toIntOrNull()
fun Parameters.getIntOrFail(name: String): Int =
getInt(name) ?: throw ParameterConversionException(name, "Int", "Cannot convert to Int")
fun Parameters.getLong(name: String): Long? = get(name)?.toLongOrNull()
fun Parameters.getLongOrFail(name: String): Long =
getLong(name) ?: throw ParameterConversionException(name, "Long", "Cannot convert to Long")
fun Parameters.getBoolean(name: String): Boolean? = get(name)?.toBooleanStrictOrNull()
fun Parameters.getBooleanOrFail(name: String): Boolean =
getBoolean(name) ?: throw ParameterConversionException(name, "Boolean", "Cannot convert to Boolean")Usage Examples:
import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.server.request.*
// Basic routing with HTTP methods
fun Application.basicRouting() {
routing {
get("/") {
call.respondText("Welcome!")
}
post("/users") {
val user = call.receive<User>()
// Create user
call.respond(HttpStatusCode.Created)
}
get("/health") {
call.respondText("OK")
}
}
}
// Path parameters and nested routes
fun Application.parameterRouting() {
routing {
route("/api/v1") {
route("/users") {
get {
// GET /api/v1/users - list all users
call.respondText("All users")
}
get("/{id}") {
val userId = call.parameters["id"]?.toIntOrNull()
?: throw BadRequestException("Invalid user ID")
// GET /api/v1/users/123
call.respondText("User $userId")
}
put("/{id}") {
val userId = call.parameters.getIntOrFail("id")
val user = call.receive<User>()
// PUT /api/v1/users/123 - update user
call.respond(user)
}
delete("/{id}") {
val userId = call.parameters.getIntOrFail("id")
// DELETE /api/v1/users/123
call.respond(HttpStatusCode.NoContent)
}
// Nested resource routes
route("/{userId}/posts") {
get {
val userId = call.parameters.getIntOrFail("userId")
// GET /api/v1/users/123/posts
call.respondText("Posts for user $userId")
}
post {
val userId = call.parameters.getIntOrFail("userId")
val post = call.receive<Post>()
// POST /api/v1/users/123/posts
call.respond(HttpStatusCode.Created, post)
}
}
}
}
}
}
// Wildcard and optional parameters
fun Application.wildcardRouting() {
routing {
// Wildcard parameter captures single segment
get("/files/{filename}") {
val filename = call.parameters["filename"]!!
call.respondText("Requested file: $filename")
}
// Tailcard captures remaining path segments
get("/static/{...}") {
val path = call.request.uri.removePrefix("/static/")
// Serve static files
call.respondText("Static path: $path")
}
// Optional parameters with defaults
get("/search") {
val query = call.request.queryParameters["q"] ?: ""
val page = call.request.queryParameters.getInt("page") ?: 1
val limit = call.request.queryParameters.getInt("limit") ?: 10
call.respondText("Search: $query, Page: $page, Limit: $limit")
}
}
}
// Route middleware and interceptors
fun Application.middlewareRouting() {
routing {
// Global interceptor for all routes
intercept(ApplicationCallPipeline.Setup) {
call.response.headers.append("X-Server", "Ktor")
}
route("/admin") {
// Authentication middleware for admin routes
intercept(ApplicationCallPipeline.Plugins) {
val token = call.request.headers["Authorization"]
if (token?.startsWith("Bearer ") != true) {
call.respond(HttpStatusCode.Unauthorized)
return@intercept finish()
}
// Validate token
}
get("/dashboard") {
call.respondText("Admin Dashboard")
}
get("/users") {
call.respondText("Admin Users")
}
}
route("/api") {
// CORS middleware for API routes
intercept(ApplicationCallPipeline.Setup) {
call.response.headers.append("Access-Control-Allow-Origin", "*")
}
get("/data") {
call.respond(mapOf("message" to "API data"))
}
}
}
}
data class User(val id: Int, val name: String, val email: String)
data class Post(val id: Int, val title: String, val content: String)Install with Tessl CLI
npx tessl i tessl/maven-io-ktor--ktor-server-core-jvm