最常见的自定义中间件写法,是 from_fn:
use axum::{
extract::Request,
middleware::Next,
response::Response,
};
async fn audit_gate(request: Request, next: Next) -> Response {
let response = next.run(request).await;
response
}但这里要注意 Axum 官方文档明确说过的一点:
from_fn 不支持直接提取 State,如果中间件里也要拿共享状态,用 from_fn_with_state。
比如:
use axum::{
extract::{Request, State},
middleware::{self, Next},
response::Response,
routing::get,
Router,
};
#[derive(Clone)]
struct AppState {
service_name: String,
}
async fn tag_request(
State(state): State<AppState>,
mut request: Request,
next: Next,
) -> Response {
request
.extensions_mut()
.insert(state.service_name.clone());
next.run(request).await
}
let state = AppState {
service_name: "north-gate".to_owned(),
};
let app = Router::new()
.route("/health", get(health))
.route_layer(middleware::from_fn_with_state(state.clone(), tag_request))
.with_state(state);这里顺手又把一件事讲透了:
State
-> 中间件和 handler 都能拿到的全局底册
Extension
-> 这次请求被中间件临时贴上的标签