Rust in Everything
基于 axum 0.8.9

中间件

axum 没有自己的中间件 trait,Router::layer 收的就是 tower 的 Layer,所以 tower 和 tower-http 的中间件可以直接用。axum 自己加了两样东西:决定 layer 套在路由树的哪些位置(每条路由、方法级 fallback、全局 fallback),以及 axum::middleware 里把普通 async fn 变成 Layer 的几个函数。Service、Layer、ServiceBuilder 本身在 tower 卷,这一部分只讲 axum 这一侧。

  1. layer 与 route_layer:Router::layer 只套调用时已有的路由和 fallback,中间件在路由之后执行;Router::route_layer 跳过 404 却仍套住 405,MethodRouter::route_layer 两者都跳过;Handler::layer 每个请求重套一遍;中间件的错误必须能转成 Infallible,否则配 HandleErrorLayer。
  2. from_fn 与它的兄弟:FromFn::call 先跑提取器、再把内层装箱成 Next;from_fn_with_state 的状态与路由器无关;map_request 能提前结束、map_response 不能;from_extractor 丢掉提取结果;每层 from_fn 每个请求的分配次数实测。
flowchart TB
  lay["tower Layer"] --> rl["Router::layer"]
  lay --> rr["route_layer"]
  lay --> ml["MethodRouter::layer"]
  lay --> hl["Handler::layer"]
  fnmw["from_fn 一族"] --> lay
  rl --> routes["每条路由与 fallback"]
  rr --> only["只套匹配到的路径"]

中间件放在 tower-http 里的那些(压缩、静态文件、超时、CORS 等)在下一部分 tower-http。

💬 关联讨论

发起讨论
加载中...