Rust Axum 框架完整介绍
Axum 是 Tokio 官方团队维护 的 Rust Web 框架,基于 Tokio异步运行时、hyper HTTP库、tower服务抽象构建,MIT协议开源,是目前Rust生态最主流的Web开发库,主打类型安全、无宏路由、可组合、极简,适合开发RESTful API、微服务、BFF网关、WebSocket服务。
当前主流版本:
0.8.x(2026稳定版),github:tokio‑rs/axum。
Axum 底层技术栈
- Tokio:Rust异步运行时,提供异步IO、任务调度;Axum强绑定Tokio,不支持其他运行时。
- hyper:高性能HTTP实现,处理TCP连接、HTTP1/HTTP2协议。
- tower / tower‑http:通用服务抽象与中间件库,Axum没有自己的中间件系统,直接复用Tower Layer,这是Axum最大特色,中间件可以和tonic(gRPC)、hyper服务共用。
- matchit:高性能路由匹配库。
- serde:JSON序列化反序列化。
Axum 核心设计理念
- 无宏路由:不用属性宏
#[get("/xxx")],全部链式API写路由,编译报错清晰,没有宏黑盒。 - Extractor(提取器):类型驱动解析请求,把path参数、query、json body、请求头、共享状态直接作为handler函数参数,编译期做类型校验,很多运行时错误直接在编译阶段拦截。
- 组合优先:Router、Layer、Handler全部可组合,Router支持嵌套,便于大项目拆分模块。
- 最小内核:框架本身只做HTTP路由分发,认证、session、模板等能力交给第三方crate。
Axum 核心组件详解
1. Router 路由器
Router是应用入口,负责路径+HTTP方法匹配,支持嵌套路由、scope分组。
use axum::{routing::{get,post}, Router};
// 基础路由
let app = Router::new()
.route("/hello", get(hello_handler))
.route("/user", post(create_user));
// 嵌套路由(分组)
let user_router = Router::new()
.route("/:id", get(get_user));
let app = app.nest("/api/user", user_router);路由语法:/:id路径参数,支持通配符/*rest。
2. Handler 处理器
就是普通async fn异步函数,输入是提取器参数,输出实现IntoResponse trait(String、Json、StatusCode、Result都实现该trait)。
注意:消耗请求体的提取器(Json、Bytes)必须放在参数列表最后。
3. Extractor 提取器(Axum灵魂)
提取器实现FromRequest / FromRequestParts trait,自动从http请求取出数据,直接作为函数入参。
| 提取器 | 作用 |
|---|---|
Path<T> | 路径参数,例Path(u64) |
Query<T> | url查询参数,T为serde结构体 |
Json<T> | 请求body json反序列化为T |
State<T> | 获取全局共享状态(线程安全) |
TypedHeader | 获取请求头 |
Bytes / String | 获取原始请求体 |
ws::WebSocketUpgrade | WebSocket升级 |
示例:
use axum::extract::{Path, Query, Json, State};
use serde::Deserialize;
#[derive(Debug, Deserialize)]
struct UserQuery {
name: String,
}
#[derive(Debug, Deserialize)]
struct CreateUser {
age: u32,
}
// 多个提取器组合
async fn handler(
Path(user_id): Path<u64>,
Query(q): Query<UserQuery>,
Json(body): Json<CreateUser>,
State(db): State<Arc<DbPool>>,
) -> String {
format!("id:{}, q:{:?}, body:{:?}", user_id, q, body)
}如果提取失败(JSON格式错误、参数类型不匹配),Axum会自动返回400错误,不会进入handler函数。
4. State 全局共享状态
用来传递数据库连接池、配置等全局资源,要求内部类型Clone + Send + Sync + 'static,一般用Arc包装。
use axum::extract::State;
use std::sync::Arc;
#[derive(Clone)]
struct AppState {
pool: sqlx::PgPool,
}
// 在router挂载state
let state = Arc::new(AppState{pool});
let app = Router::new()
.route("/",get(root))
.with_state(state);对比
Extension<T>:Extension是动态类型,运行时查找;State是编译期类型安全,优先使用State。
5. Tower Layer 中间件
Axum中间件全部来自tower‑http,通过.layer()挂载;layer执行顺序:后添加的layer最外层,最先执行。
常用tower‑http中间件:
TraceLayer:请求日志、trace追踪CorsLayer:跨域CORSCompressionLayer:gzip压缩TimeoutLayer:请求超时SetRequestIdLayer:生成请求ID
use tower_http::{trace::TraceLayer, cors::{CorsLayer, Any}};
let app = Router::new()
.route("/",get(h))
.layer(TraceLayer::new_for_http())
.layer(CorsLayer::new().allow_origin(Any));自定义中间件:实现tower::Layer、tower::Service trait。
6. 错误处理
handler返回Result<T, E>,只要E实现IntoResponse就可以自动转为HTTP响应。 推荐自定义AppError,统一处理业务错误、数据库错误。
async fn handler() -> Result<Json<User>, AppError> {
let user = db.query_user().await?;
Ok(Json(user))
}7. WebSocket支持
内置axum::extract::ws,轻松实现ws长连接:
use axum::extract::ws::{WebSocket, WebSocketUpgrade};
async fn ws_handler(ws: WebSocketUpgrade) -> impl IntoResponse {
ws.on_upgrade(|socket: WebSocket| async move {
// socket读写消息
})
}Axum 完整最小可运行示例
Cargo.toml依赖:
[dependencies]
axum = "0.8"
tokio = { version = "1.0", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
tower-http = {version="0.5", features=["trace","cors"]}main.rs
use axum::{routing::get, Router};
use tower_http::trace::TraceLayer;
async fn hello() -> &'static str {
"Hello Axum!"
}
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/", get(hello))
.layer(TraceLayer::new_for_http());
println!("listening 127.0.0.1:3000");
axum::Server::bind(&"127.0.0.1:3000".parse().unwrap())
.serve(app.into_make_svc())
.await
.unwrap();
}Axum vs Actix‑Web(2026主流对比)
| 维度 | Axum | Actix‑Web |
|---|---|---|
| 运行时 | 原生Tokio | 自定义Actor模型,底层Tokio |
| 路由 | 无宏链式Router | 属性宏#[get("/")] |
| 中间件 | Tower Layer生态,可与tonic/gRPC复用 | 框架自有中间件体系 |
| 状态管理 | State<T>编译期类型安全 | web::Data<T> |
| 开发体验 | 报错友好,贴近现代Rust | 部分场景报错晦涩 |
| 性能 | 极高,绝大多数业务够用 | 基准跑分略高,极限QPS更强 |
| 适用场景 | 新项目、微服务、gRPC+HTTP混合、团队新手 | Rust老项目、超高吞吐场景 |
现实业务中,数据库、IO才是瓶颈,框架本身差距几乎感知不到,新项目优先选Axum。
Axum生态常用配套crates
- sqlx:数据库访问(Postgres/MySQL/SQLite),和Axum做API非常常用
- tracing + tracing‑subscriber:日志,配合TraceLayer
- axum‑extra:辅助工具,OpenAPI文档、请求校验
- utoipa:自动生成OpenAPI/Swagger文档
- axum‑server:生产环境服务(优雅关闭、tls)
- thiserror:自定义业务错误
Axum 优缺点总结
✅ 优点
- Tokio官方维护,生态统一,和tonic(gRPC)完美协同
- 提取器系统,大量错误编译期发现,线上bug更少
- tower中间件生态强大,开箱即用日志、CORS、超时、压缩
- API干净,无魔法,没有大量宏,代码可读性高
- 支持WebSocket、SSE,适合现代API服务
❌ 缺点
- 强绑定Tokio运行时,不能换其他runtime
- 框架“薄”,没有内置session、模板,需要自己组合第三方库
- body提取器有参数顺序限制,新手容易踩坑
Axum 适合什么项目
- RESTful API后端、微服务、BFF层
- 需要同时提供HTTP + gRPC服务(复用Tower中间件)
- Rust新项目,希望写类型安全、易维护Web服务
- 网关、代理服务
不适合:需要大而全开箱即用全栈框架(可以选loco,基于axum的全栈框架)。