Routers and multiple files¶
A router class groups static handlers under a path prefix. Mounting adds an optional application-specific prefix.
import system;
import system.webapi;
@router("/users")
class Routes {
@get("/{id}")
public static fun user(@path id: int): string {
return id.to_string();
}
}
async fun main(): void {
let app = WebApp();
app.include_router(Routes.router(), "/v1").unwrap();
app.run("127.0.0.1", 8000).await.unwrap();
}
This app exposes /v1/users/{id}. Mount the same descriptor on another app with /v2 without changing the router.
Route attributes¶
| Attribute | Put on | Effect |
|---|---|---|
@router(prefix) |
Class | Groups the class's static handlers under prefix and generates ClassName.router(). Use "" for no prefix. |
@get(path) |
Static method | Handles GET requests to path. |
@post(path) |
Static method | Handles POST requests. |
@put(path) |
Static method | Handles PUT requests. |
@patch(path) |
Static method | Handles PATCH requests. |
@delete(path) |
Static method | Handles DELETE requests. |
@head(path) |
Static method | Handles HEAD requests. A @get route already answers HEAD for its path, so use this only when HEAD needs different behavior. |
@options(path) |
Static method | Handles OPTIONS requests. |
@websocket(path) |
Static method | Upgrades the request to a WebSocket. |
@use(middleware) |
Class or static method | Runs a middleware function around the group or route; repeatable. |
Route paths are relative to the router prefix. Write a named segment as {name} and bind it with a parameter of the same name. Other per-route attributes are covered in their guides: @operation and @response, @requires_scopes, and @produces.
How a request finds its route¶
Routes are tried in the order they were mounted, and within a router in declaration order. The first route whose path and method both match handles the request, so a fixed path such as /users/me must come before /users/{id} to be reachable.
- A
HEADrequest is served by the first matching@getroute. The response carries the same status and headers asGETbut no body. - When the path matches but no route accepts the method, the response is 405 Method Not Allowed, with an
Allowheader listing the methods the path does accept (for exampleAllow: GET, HEAD, POST). - When no route matches the path, the response is 404 Not Found.
Mounting¶
WebApp method |
Effect |
|---|---|
include_router(router, prefix = "") |
Serves and documents every route in router, with prefix added in front of the router's own prefix. |
For multiple files, put a public router class in users.dream, import that file from the application entry point, and call app.include_router(Users.router()).unwrap(). Put request/response models and account repositories in their own files. The complete example shows the exact layout.
Only explicitly mounted routers are served or documented. Duplicate methods and paths within one router are compile-time errors. Duplicate routes introduced by mounting are startup errors. Keep endpoint names and paths stable when clients use the generated OpenAPI operation IDs.
See the API lookup and complete example.