Skip to content

Routing

Routes live in src/routes/*.rs. Each file exports a register(app) function that the RouteServiceProvider calls at boot.

Basic example

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Public API surface. Health check, a few read endpoints.
|
*/
use oxide_http::prelude::*;
pub fn register(app: &Application) {
app.get("/health", |_req: Request| async { "ok" });
app.post("/auth/login", LoginController::login);
}

Grouping

app.group(prefix, closure) prefixes every route inside:

app.group("/api/v1", |r| {
r.get("/health", health_handler);
r.get("/app-info", app_info_handler);
r.group("/admin", |rr| {
rr.get("/stats", StatsController::index);
});
});

Attaching middleware

app.middleware([...]) returns a group that carries the listed middleware. Any route registered on it — directly or via a nested .group(...) — runs inside the chain.

use oxide_auth::auth_middleware;
use crate::app::domain::user::models::User;
app.middleware([auth_middleware::<User>()])
.get("/me", UserController::me)
.post("/auth/logout", AuthController::logout);

Chain multiple middleware and nest:

app.middleware([auth_middleware::<User>()])
.group("/admin", |r| {
r.middleware([abilities(["admin:*"])])
.get("/users", AdminController::list_users)
.delete("/users/{id}", AdminController::delete_user);
});

Path parameters

Curly-brace syntax: /todos/{id}. In a stateless controller, extract them from the request:

async fn show(req: Request) -> Response {
let Some(id) = req.param("id").and_then(|s| s.parse::<i64>().ok()) else {
return Response::with_status(StatusCode::BAD_REQUEST);
};
// ...
Response::text("ok")
}

For #[api_resource] controllers, path params become typed args automatically: async fn show(&self, id: i64) -> Response { ... }.

Registering your route file

Add pub mod <name>; inside src/routes/mod.rs, then a call in src/providers/route_service_provider.rs:

pub struct RouteServiceProvider;
impl ServiceProvider for RouteServiceProvider {
fn register(&self, app: &Application) {
routes::api::register(app);
routes::admin::register(app);
}
}