全书目录

第三十九篇:Axum 完全指南 —— Rust 类型关口宇宙

第十三章:自定义中间件 —— 安检员不是魔法师,本质还是函数和 Layer

1 分钟 124 字 第 759 / 962 个阅读单元

最常见的自定义中间件写法,是 from_fn

rust
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

比如:

rust
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);

这里顺手又把一件事讲透了:

text
State
-> 中间件和 handler 都能拿到的全局底册

Extension
-> 这次请求被中间件临时贴上的标签