全书目录

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

第十五章:自定义 Extractor —— 这才是 Axum 最像“类型关口”的地方

1 分钟 196 字 第 761 / 962 个阅读单元

如果说 StateJson 只是用现成验货设备,那自定义 extractor 才是“自己造海关扫描仪”。

比如,我们定义一个“当前关员”提取器:

rust
use axum::{
    extract::FromRequestParts,
    http::{
        header::AUTHORIZATION,
        request::Parts,
    },
};

struct CurrentOfficer {
    name: String,
}

impl<S> FromRequestParts<S> for CurrentOfficer
where
    S: Send + Sync,
{
    type Rejection = ApiError;

    async fn from_request_parts(
        parts: &mut Parts,
        _state: &S,
    ) -> Result<Self, Self::Rejection> {
        let value = parts
            .headers
            .get(AUTHORIZATION)
            .and_then(|v| v.to_str().ok());

        match value {
            Some("Bearer gate-secret") => Ok(Self {
                name: "north-gate-officer".to_owned(),
            }),
            _ => Err(ApiError::Unauthorized),
        }
    }
}

然后 handler 就可以直接这么写:

rust
async fn my_profile(officer: CurrentOfficer) -> String {
    format!("当前执勤关员:{}", officer.name)
}

这时候心智就非常美:

text
Handler 不再自己拆 Header
而是直接声明:
“我这个窗口只接收已经验明身份的关员”

你会发现,Axum 的优雅感很大一部分就来自这里:

很多原本散落在 handler 里的脏活,可以被抽成类型化的提取器。

这会让你的窗口函数越来越像业务声明,而不是流水线噪音。