Extracteurs de paramètres
Path — Paramètres d'URL
Valeur typée — request.get_path_as()
Parse le segment d'URL directement dans le type cible.
Retourne None si la clé est absente ou si la valeur ne peut pas être parsée.
// Route : "/menus/{id}"
async fn menu_detail(mut request: Request) -> AppResult<Response> {
let Some(id) = request.get_path_as::<i32>("id") else {
return Ok((StatusCode::NOT_FOUND, "Introuvable").into_response());
};
// id = 42 pour /menus/42
}
Chaîne brute — request.get_path()
async fn article(mut request: Request) -> AppResult<Response> {
let slug = request.get_path("slug").unwrap_or_default();
}
Plusieurs segments — extracteur Axum Path
Pour extraire plusieurs segments à la fois, l'extracteur Axum reste disponible :
use axum::extract::Path;
#[derive(Deserialize)]
pub struct UserPostPath {
user_id: i32,
post_id: i32,
}
async fn user_post(
Path(params): Path<UserPostPath>,
mut request: Request,
) -> AppResult<Response> {
// params.user_id, params.post_id
}
Query — Paramètres de requête
Struct typée — request.query()
Désérialise la query string complète vers une struct dérivant Deserialize.
Les clés inconnues sont ignorées ; une valeur vide (?page=) est retirée, un champ Option reçoit alors None.
Une query string qui ne correspond pas à la struct (?page=abc pour un u32) est une 400 Bad Request : avec ?, le handler s'arrête et 400.html est affiché. Ce template se surcharge comme 404.html, en plaçant le vôtre dans templates/. En mode debug, la page indique quel paramètre a échoué et pourquoi.
#[derive(Deserialize)]
pub struct Filtres {
page: Option<u32>,
limit: Option<u32>,
recherche: Option<String>,
}
async fn liste(mut request: Request) -> AppResult<Response> {
let filtres: Filtres = request.query()?;
let page = filtres.page.unwrap_or(1);
// ...
}
Valeur unique — request.get_query(clé)
async fn liste(mut request: Request) -> AppResult<Response> {
let page: u32 = request.get_query("page")
.and_then(|v| v.parse().ok())
.unwrap_or(1);
// ...
}
Headers — `request.headers`
La map HTTP complète des en-têtes est accessible directement sur Request. Utile pour lire Host, Accept-Language, des en-têtes custom, etc.
async fn handler(mut request: Request) -> AppResult<Response> {
// Une URL absolue (lien envoyé par email…) part de l'URL publique
// (`.with_public_url()`), jamais du
// header Host : le client le choisit, et un lien vers son site emporterait
// le jeton qu'il contient.
let base_url = request.engine.config.server.public_url.clone();
// Lire n'importe quel header
let lang = request.headers
.get("accept-language")
.and_then(|v| v.to_str().ok())
.unwrap_or("fr");
}
request.headers est de type axum::http::HeaderMap, re-exporté dans le prelude.
Base de données — `request.db()`
Retourne la connexion du moteur (&ADb), prête à passer aux requêtes SeaORM.
async fn handler(mut request: Request) -> AppResult<Response> {
let db = request.db();
let item = MyEntity::find_by_id(1).one(db).await?;
// ...
}
Équivalent à &request.engine.db, en plus court.
Formulaires — `req.form("nom")`
use runique::prelude::*;
async fn signup(mut request: Request) -> AppResult<Response> {
let form: SignupForm = request.form("signup");
let form = match ValidationForm::try_form(form, &request).await {
Ok(validated) => match validated.save(&request.engine.db).await {
Ok(_) => return Ok(Redirect::to("/").into_response()),
Err(form) => form,
},
Err(form) => form,
};
context_update!(request => { "signup_form" => &form });
request.render("signup.html")
}
request.form("nom") construit le formulaire avec les données envoyées ; ValidationForm::try_form le valide s'il a bien été envoyé. Voir Concepts clés.
Json — Corps JSON
use axum::Json;
#[derive(Deserialize)]
pub struct CreateUserRequest {
username: String,
email: String,
}
async fn create_api(
Json(payload): Json<CreateUserRequest>,
) -> impl IntoResponse {
// payload.username, payload.email
}