全书目录

第四十四篇:Rocket 完全指南 —— 火箭发射控制塔宇宙

第十一章:Fairings —— 全塔级挂钩设施,不是每个发射口都手装一遍

2 分钟 505 字 第 820 / 962 个阅读单元

Rocket 里的 fairing,可以理解成:

控制塔的全局挂钩设施。

比如:

  • 日志记录
  • 统一响应头
  • 启动时初始化
  • 请求计时
  • 响应加工
  • 全局指标采集

官方也很明确提醒了一件事:

fairing 是 Rocket 提供的更简单的结构化中间件方式,但并不适合所有细粒度控制。很多情况下,request guard 或 data guard 会更干净。

这句话特别重要。

因为很多人会把 fairing 理解成“Rocket 版万能 middleware”。

不完全对。

更准确地说:

  • guard 更像发射前检查员
  • fairing 更像整座控制塔统一安装的设施

一个请求计时 fairing 例子大致像这样:

rust
use rocket::{Data, Request, Response};
use rocket::fairing::{Fairing, Info, Kind};

pub struct RequestTimer;

#[rocket::async_trait]
impl Fairing for RequestTimer {
    fn info(&self) -> Info {
        Info {
            name: "Request Timer",
            kind: Kind::Request | Kind::Response,
        }
    }

    async fn on_request(&self, req: &mut Request<'_>, _data: &mut Data<'_>) {
        req.local_cache(|| std::time::SystemTime::now());
    }

    async fn on_response<'r>(&self, req: &'r Request<'_>, res: &mut Response<'r>) {
        let start = req.local_cache(|| std::time::SystemTime::now());
        if let Ok(duration) = start.elapsed() {
            res.set_raw_header("x-response-time-ms", duration.as_millis().to_string());
        }
    }
}

然后在构建时 attach:

rust
rocket::build().attach(RequestTimer)

你可以把它理解成:

控制塔统一给所有发射任务挂上计时器。

不是某个单独发射员临时拿秒表。

#Rocket 对 fairing 的真实态度

这点一定要讲透:

Rocket 官方文档明确提过,很多看似想用 fairing 做的事情,实际上更适合用 request guard、data guard 这些更可组合的机制。

所以别把 fairing 当成“一切都往这里塞”的万能箱。