Controllers and Routing
Relevant source files
The following files were used as context for generating this wiki page:
Controllers in Loco act as the primary interface for handling web requests, processing parameters, and rendering content-aware responses. Built upon the Axum framework, the routing system provides a declarative way to map HTTP URIs and methods to specific asynchronous functions, supporting advanced features like nesting, path normalization, and middleware integration.
Sources: docs-site/config.toml:132-137, src/controller/app_routes.rs:1-4
Core Components
The routing architecture is built around three primary data structures that define how requests flow through the application.
Routes and Handlers
The Routes struct represents a collection of URI-to-method mappings, typically defined within a single controller. Each Handler within Routes defines the specific URI, the associated Axum MethodRouter, and the supported HTTP methods (GET, POST, etc.).
Sources: src/controller/routes.rs:8-12, src/controller/routes.rs:15-19
AppRoutes
The AppRoutes struct serves as the global registry for the application. It aggregates multiple Routes instances from different controllers and manages global path prefixes and middleware layers.
Sources: src/controller/app_routes.rs:21-25
Component Summary Table
| Component | Description | Primary Responsibility |
|---|---|---|
Handler | Individual endpoint definition | Maps a URI to an async function and HTTP methods. |
Routes | Controller-level route set | Groups handlers and allows local prefixing/nesting. |
AppRoutes | Global application routing | Manages the router "onion" and global prefixes. |
ListRoutes | Internal representation | Used for route discovery and CLI display. |
Sources: src/controller/routes.rs:8-19, src/controller/app_routes.rs:21-32
Route Architecture and Flow
Loco follows an "onion" architecture when building the final Axum router. Middleware layers are wrapped around the core application routes, where the last middleware added is the first to process an incoming request (LIFO order).
The diagram shows the flow of a request from the outer middleware layers through to the core controller logic.
Sources: src/controller/app_routes.rs:230-245
Routing Logic and Prefixes
Loco provides several methods to organize URIs, primarily through prefixing and nesting.
Prefixing and Nesting Methods
prefix(str): Sets a base path for all routes in the set. It ensures paths start with/and end with/for consistency.nest_prefix(str): Appends a new segment to the existing prefix.nest_route(prefix, Routes): Scopes a specific set of controller routes under a new prefix without affecting other routes in theAppRoutesregistry.
Sources: src/controller/app_routes.rs:104-118, src/controller/app_routes.rs:141-150, src/controller/routes.rs:205-215
URL Normalization
During the route collection process, Loco automatically normalizes URIs by replacing multiple slashes with a single slash and stripping trailing slashes (unless the path is the root /).
Sources: src/controller/app_routes.rs:14-18, src/controller/app_routes.rs:59-70
Relationships between routing structures and their nesting capabilities.
Sources: src/controller/routes.rs:8-19, src/controller/app_routes.rs:21-25
CLI Integration and Introspection
Loco provides built-in tools to inspect and debug the route configuration via the command line.
Route Discovery
Using the cargo loco routes command, developers can view a tree-like representation of all registered endpoints, including their HTTP methods and full URIs.
Sources: src/cli.rs:90-91, src/cli.rs:645-660
Middleware Inspection
The cargo loco middleware --config command displays active middleware layers and their specific configurations (e.g., whether they are enabled and their priority in the stack).
Sources: src/cli.rs:93-97, src/cli.rs:434-445
Dynamic Content Handling
Controllers in Loco are "content-aware." This means a single action can respond with different formats (HTML, JSON, Text) based on request headers or explicitly defined logic.
pub async fn get_one(
respond_to: RespondTo,
Path(id): Path<i32>,
State(ctx): State<AppContext>,
) -> Result<Response> {
let item = Notes::find_by_id(id).one(&ctx.db).await?;
match respond_to {
RespondTo::Html => html_view(&item),
_ => format::json(item),
}
}
Sources: docs-site/config.toml:139-148
Summary
The routing system in Loco provides a hierarchical structure for managing web endpoints. By utilizing Routes for controller-level organization and AppRoutes for global application configuration, the framework ensures that URI patterns remain consistent through automated normalization. The deep integration with Axum allows for high-performance request handling, while the Loco CLI provides necessary visibility into the resulting router and middleware stack.
Sources: src/controller/app_routes.rs:1-4, src/cli.rs:645-650