Controllers
Controllers are injectable providers with route metadata generated by #[controller].
#![allow(unused)]
fn main() {
use std::sync::Arc;
use caelix::{Response, Result, StatusCode, controller, injectable};
use serde::{Deserialize, Serialize};
#[derive(Deserialize)]
pub struct ListUsersQuery {
pub limit: Option<usize>,
}
#[derive(Deserialize)]
pub struct CreateUserDto {
pub email: String,
pub name: String,
}
#[derive(Serialize)]
pub struct UserDto {
pub id: i64,
pub email: String,
pub name: String,
}
#[injectable]
pub struct UsersController {
users: Arc<UsersService>,
}
#[controller("/users")]
impl UsersController {
#[get("")]
pub async fn list(&self, #[query] query: ListUsersQuery) -> Result<Vec<UserDto>> {
self.users.list(query.limit).await
}
#[get("/{id}")]
pub async fn get_user(&self, #[param] id: i64) -> Result<UserDto> {
self.users.find(id).await
}
#[post("")]
pub async fn create_user(&self, #[body] input: CreateUserDto) -> Result<Response<UserDto>> {
let user = self.users.create(input).await?;
Ok(Response::WithStatus(StatusCode::CREATED, user))
}
}
}
Supported route attributes are #[get], #[post], #[patch], #[put], and #[delete].
Controller parameters use #[param], #[query], #[body], #[file],
#[files], #[multipart], #[user], and #[cookie("name")].
#[validate] validates a decoded value. See the canonical Extractors
guide for accepted Rust types, feature requirements, combinations, order, and
error behavior. Extractor arguments must be simple identifiers.
Routing example
A single path segment can be extracted directly:
#![allow(unused)]
fn main() {
#[get("/{id}")]
pub async fn find(&self, #[param] id: i64) -> Result<UserDto> {
self.users.find(id).await
}
}
For multiple path params, use a tuple or a Serde-deserializable struct:
#![allow(unused)]
fn main() {
#[get("/{org_id}/users/{user_id}")]
pub async fn find_in_org(&self, #[param] ids: (i64, i64)) -> Result<UserDto> {
let (org_id, user_id) = ids;
self.users.find_in_org(org_id, user_id).await
}
}
Generated Route Metadata
The macro implements Controller for the type. Registered routes are exposed through Controller::routes() and logged at application startup. Display paths use :id style in logs, even though route attributes use Actix’s {id} syntax.