Routing APIThe module provides a high-performance routing mechanism based on a Radix Tree implementation. It supports standard HTTP methods and dynamic path parameters.

Routing API

The aether-web module provides a high-performance routing mechanism based on a Radix Tree implementation. It supports standard HTTP methods and dynamic path parameters.

Router

The Router class allows you to define routes and their handlers using a clean DSL.

Basic Usage

val appRouter = router {
    get("/") { exchange ->
        exchange.respond(body = "Welcome to Aether")
    }

    post("/api/data") { exchange ->
        // Handle POST request
    }
}

Route Methods

The Router supports the following HTTP methods:

  • get(path: String, handler: RouteHandler)
  • post(path: String, handler: RouteHandler)
  • put(path: String, handler: RouteHandler)
  • delete(path: String, handler: RouteHandler)
  • patch(path: String, handler: RouteHandler)
  • head(path: String, handler: RouteHandler)
  • options(path: String, handler: RouteHandler)

Path Parameters

Routes can include dynamic parameters prefixed with a colon (:). These parameters are extracted and made available in the Exchange.attributes.

get("/users/:id") { exchange ->
    val userId = exchange.pathParam("id")
    exchange.respond(body = "User ID: $userId")
}

Radix Tree

Under the hood, Router maintains a separate RadixTree for each HTTP method. This ensures:

  • O(k) lookup time, where k is the length of the path.
  • Efficient storage of routes sharing common prefixes.
  • Fast parameter extraction.

Integration with Pipeline

The Router can be converted into a middleware for easy integration into the main application pipeline:

val pipeline = Pipeline()
pipeline.use(router.asMiddleware())

REST ViewSets and Resources

Aether supports defining RESTful resources using the ViewSet interface, similar to other frameworks like Django or Rails. This provides a structured way to handle standard CRUD operations.

ViewSet Interface

Implement ViewSet<T> or extend BaseViewSet<T> (which provides default 405 Method Not Allowed implementations):

interface ViewSet<T> {
    suspend fun list(exchange: Exchange): List<T>
    suspend fun create(exchange: Exchange): T
    suspend fun retrieve(exchange: Exchange, id: String): T?
    suspend fun update(exchange: Exchange, id: String): T
    suspend fun delete(exchange: Exchange, id: String): Boolean
}

Registering a Resource

Use the resource extension function on the Router to register a ViewSet. You must provide a serializer for the model.

@Serializable
data class Todo(val id: Int, val title: String)

class TodoViewSet : BaseViewSet<Todo>() {
    override suspend fun list(exchange: Exchange): List<Todo> {
        return listOf(Todo(1, "Buy milk"))
    }
    // ... implement other methods
}

val appRouter = router {
    // Registers GET /todos, POST /todos, GET /todos/:id, PUT /todos/:id, DELETE /todos/:id
    resource("/todos", TodoViewSet(), Todo.serializer())
}
Architected in Kotlin. Rendered with Materia. Powered by Aether.
© 2026 Yousef.?