
axum基于 tower 生态的 Rust HTTP 路由与请求处理库【免费下载链接】axumHTTP routing and request-handling library for Rust that focuses on ergonomics and modularity项目地址: https://gitcode.com/GitHub_Trending/ax/axumaxum是 Rust 生态中一个专注于**易用性ergonomics与模块化modularity**的 HTTP 路由与请求处理库。它不发明自己的中间件体系而是直接构建在 [tower::Service] 之上从而天然获得超时、追踪、压缩、鉴权等成熟能力。本文以 axum/README.md 为骨架结合仓库源码与示例系统讲解 axum 的核心特性、快速上手方式、运行模型、性能与安全保证并深入到Router、Handler、Extractor 与axum::serve的源码实现帮助你快速掌握用它搭建 Web 服务的能力。一、axum 是什么axum定位为HTTP 路由与请求处理库HTTP routing and request-handling library它的设计目标是让开发者以最少的样板代码完成「路由 → 处理 → 响应」的完整链路。它本身不是一个全家桶式框架而是一个薄薄地叠在 [hyper] 之上的库这一点在后续「性能」一节会再次强调。在仓库根目录的 Cargo.toml 中可以看到工作区由多个 crate 组成其中axum本仓库 axum/Cargo.toml当前版本 0.8.9是主 crate另有axum-core、axum-extra、axum-macros三个配套 crate分别承载核心 trait 与类型、额外扩展能力、过程宏。主 crate 的 description 与 README 首句一致HTTP routing and request handling library that focuses on ergonomics and modularity二、高层特性一览README 将 axum 的核心能力归纳为五条这也是理解它设计哲学的入口特性含义宏无关的路由 API使用Router::new().route(...)链式调用注册路由无需任何路由宏声明式请求解析Extractor通过提取器extractor按声明式方式拆解请求如JsonT、PathT、QueryT简单可预测的错误处理模型错误可以轻松转换为响应且保证所有错误都被处理极简样板生成响应任何实现了IntoResponse的类型都能直接作为 handler 的返回值完整利用 tower / tower-http 生态超时、tracing、压缩、鉴权等中间件开箱即用其中最后一条正是 README 特别强调的、将 axum 与其他库/框架区分开来的关键点In particular the last point is what setsaxumapart from other libraries / frameworks.这句话在 axum/src/lib.rs 的 crate 文档开头被原样保留说明它是 axum 的核心卖点。三、为什么说 tower 生态是 axum 的基石axum没有自己的中间件系统而是直接使用 [tower::Service] trait 作为统一的抽象。这意味着免费获得成熟能力超时timeout、链路追踪tracing、压缩compression、鉴权authorization等中间件直接从tower与tower-http生态中拿来即用无需自行实现跨框架共享中间件基于tower::Service编写的中间件可以同时用于 [hyper] 或 [tonic]gRPC应用实现中间件的「一次编写、多处复用」。从源码结构看这一设计贯穿始终axum/src/routing/mod.rs 中Router内部由PathRouter、fallback 等组件构成最终通过tower_service::Servicetrait 暴露为服务axum/src/handler/mod.rs 中Handlertrait 定义了「异步函数 → 请求处理」的抽象并可通过HandlerWithoutStateExt::into_service或Handler::with_state转换为tower::Serviceaxum/src/serve/mod.rs 的axum::serve接收实现了Service的make_service配合 hyper-util 完成 HTTP/1 与 HTTP/2 的连接服务。在依赖层面axum/Cargo.toml 明确声明了对tower { version 0.5.2, default-features false, features [util] }、tower-layer、tower-service的依赖并且tower-http作为可选依赖提供了timeout、trace、compression-gzip、cors、request-id等一长串中间件特性见该文件[dependencies.tower-http]段落。使用中间件的最小示意use axum::{Router, routing::get, middleware}; use tower_http::timeout::TimeoutLayer; use std::time::Duration; let app Router::new() .route(/, get(handler)) .layer(TimeoutLayer::new(Duration::from_secs(5))); async fn handler() - static str { Hello, World! }四、快速上手Hello World 与完整示例1. 添加依赖根据 axum/src/lib.rs 中「Required dependencies」一节的说明使用 axum 至少需要引入以下依赖[dependencies] axum latest-version tokio { version latest-version, features [full] } tower latest-version其中tokio 的full特性并非必需但它是快速开始最省事的方式tower也非严格必需但对编写测试很有帮助仓库的 testing 示例展示了如何用 tower 测试 axum 应用如果用到serde做 JSON 序列化Json提取器还需要引入serde的derive特性。2. 完整使用示例README 给出了一个同时包含路由注册、JSON 提取器、JSON 响应、状态码返回的完整示例这也是仓库 examples/readme/src/main.rs 的可运行代码运行命令为cargo run -p example-readmeuse axum::{ routing::{get, post}, http::StatusCode, Json, Router, }; use serde::{Deserialize, Serialize}; #[tokio::main] async fn main() { // initialize tracing tracing_subscriber::fmt::init(); // build our application with a route let app Router::new() // GET / goes to root .route(/, get(root)) // POST /users goes to create_user .route(/users, post(create_user)); // run our app with hyper, listening globally on port 3000 let listener tokio::net::TcpListener::bind(0.0.0.0:3000).await.unwrap(); axum::serve(listener, app).await; } // basic handler that responds with a static string async fn root() - static str { Hello, World! } async fn create_user( // this argument tells axum to parse the request body // as JSON into a CreateUser type Json(payload): JsonCreateUser, ) - (StatusCode, JsonUser) { // insert your application logic here let user User { id: 1337, username: payload.username, }; // this will be converted into a JSON response // with a status code of 201 Created (StatusCode::CREATED, Json(user)) } // the input to our create_user handler #[derive(Deserialize)] struct CreateUser { username: String, } // the output to our create_user handler #[derive(Serialize)] struct User { id: u64, username: String, }这段代码的工程要点非常密集值得逐行拆解Router::new()构建路由.route(/, get(root))把GET /路由到root.route(/users, post(create_user))把POST /users路由到create_user。同一路径可以链式绑定多个方法例如.route(/foo, get(get_foo).post(post_foo))这在 axum/src/lib.rs 的「Routing」一节有更完整的演示Extractor 自动解析Json(payload): JsonCreateUser告诉 axum 把请求体按 JSON 解析成CreateUser类型serde::Deserialize负责反序列化解析失败时会走 axum 内置的拒绝rejection机制最终转换为错误响应IntoResponse驱动响应static str自动变成200 OK且content-type: text/plain; charsetutf-8的响应(StatusCode, JsonT)元组则自动组合为「指定状态码 JSON 体」的响应这里返回201 Createdaxum::serve启动服务tokio::net::TcpListener::bind(0.0.0.0:3000)绑定监听地址后axum::serve(listener, app)在 hyper 之上接管连接并分发到路由。它同时支持 HTTP/1 与 HTTP/2见 axum/src/serve/mod.rs 的文档说明。示例的依赖配置见 examples/readme/Cargo.toml它只依赖axum、serde带 derive、tokiofull、tracing与tracing-subscriber是最精简的可运行组合。五、运行模型Handler、Extractor 与 IntoResponseREADME 的示例背后是 axum 三大核心抽象Handler处理器、Extractor提取器、IntoResponse响应转换。1. Handler异步函数即处理器从 axum/src/handler/mod.rs 与 axum/src/docs/handlers_intro.md 可知In axum a handler is an async function that accepts zero or more extractors as arguments and returns something that can be converted into a response.即 handler 是接受零个或多个提取器作为参数、返回可转换为响应的值的异步函数。应用逻辑都写在 handler 里axum 应用本质上就是「在 handler 之间路由」。Handlertrait 还会自动为T: IntoResponse的类型实现因此可以给路由挂一个固定响应而不写函数use axum::{Router, routing::{get, post}, Json, http::StatusCode}; use serde_json::json; let app Router::new() // respond with a fixed string .route(/, get(Hello, World!)) // or return some mock data .route(/users, post(( StatusCode::CREATED, Json(json!({ id: 1, username: alice })), )));2. Extractor声明式拆解请求提取器是实现FromRequest或FromRequestParts的类型是「把请求拆解成 handler 需要的部分」的手段见 axum/src/lib.rs 的「Extractors」一节与 axum/src/extract/mod.rsuse axum::extract::{Path, Query, Json}; use std::collections::HashMap; // Path gives you the path parameters and deserializes them. async fn path(Path(user_id): Pathu32) {} // Query gives you the query parameters and deserializes them. async fn query(Query(params): QueryHashMapString, String) {} // Buffer the request body and deserialize it as JSON into a // serde_json::Value. Json supports any type that implements // serde::Deserialize. async fn json(Json(payload): Jsonserde_json::Value) {}axum 内置的提取器覆盖了常见场景其中不少通过 feature flag 控制详见下文第八节Path解析路径参数并反序列化Query解析查询字符串需queryfeature默认开启Json缓冲请求体并反序列化为任意serde::Deserialize类型需jsonfeature默认开启Form解析application/x-www-form-urlencoded表单需formfeature默认开启Multipart解析multipart/form-data需multipartfeatureExtension/State从请求扩展或应用状态中取值MatchedPath获取请求匹配到的路由路径需matched-pathfeature默认开启OriginalUri获取请求的原始 URI需original-urifeature默认开启WebSocketUpgradeWebSocket 升级需wsfeature。3. IntoResponse一切皆可响应任何实现IntoResponse的类型都可以作为 handler 的返回值见 axum/src/lib.rs 的「Responses」一节use axum::{body::Body, routing::get, response::Json, Router}; use serde_json::{Value, json}; // static str becomes a 200 OK with content-type: text/plain; charsetutf-8 async fn plain_text() - static str { foo } // Json gives a content-type of application/json and works with any type // that implements serde::Serialize async fn json() - JsonValue { Json(json!({ data: 42 })) } let app Router::new() .route(/plain_text, get(plain_text)) .route(/json, get(json));ResultT, E其中T、E均实现IntoResponse也是合法的返回类型这让 handler 里可以放心使用?运算符传播错误。仓库的 examples/error-handling/src/main.rs 与 examples/anyhow-error-response/src/main.rs 分别展示了「应用级自定义错误」与「通用 boxed 错误」两种错误处理范式。六、在 handler 之间共享状态README 未展开但 axum/src/lib.rs 深入讲解了一个高频需求在多个 handler 之间共享状态如数据库连接池、外部服务客户端。官方文档给出四种方式State提取器推荐类型最安全先用.with_state(shared_state)注入状态handler 中通过State(state): StateArcAppState提取。状态会为每个请求克隆一次用Arc包裹可使克隆廉价如果状态内部字段本身就是Arc或 Copy 类型如reqwest::Client则无需再包一层Arc请求扩展Extension通过.layer(Extension(shared_state))注入、Extension(state)提取。缺点是没有编译期检查取不到扩展时会在运行时返回500 Internal Server Error闭包捕获把状态move进闭包再传给 handler最直观但最冗长任务局部变量task-local用tokio::task_local!在中间件中写入、在 handler 与IntoResponse实现中读取适合「每个请求一个用户身份」这类场景但依赖执行器对 task-local 的支持。此外还有两个进阶技巧值得了解子状态FromRef当 handler 只需要应用状态的一部分时实现FromRefAppState for ApiState或#[derive(FromRef)]需macrosfeaturehandler 只提取需要的子状态RouterS泛型参数RouterSS非()表示「缺少类型为S的状态」的路由器调用.with_state(s)后通常得到Router()——只有Router()才能传给axum::serve。这一类型层面的约束可以在编译期阻止「忘记注入状态」的错误。七、性能与安全保证性能hyper 之上的薄层README 明确说明axumis a relatively thin layer on top ofhyperand adds very little overhead. Soaxums performance is comparable tohyper.即 axum 是叠加在hyper之上的相对较薄的一层额外开销极小性能与hyper相当。这一点也能从源码结构得到印证Router的请求分发最终落到matchit路径匹配器与各个 handler/service 上核心链路没有引入昂贵的抽象。仓库的基准测试位于 axum/benches/benches.rs。安全100% Safe RustREADME 声明 crate 使用了#![forbid(unsafe_code)]来保证所有实现都是 100% Safe Rust。在 axum/src/lib.rs 中可以看到#![forbid(unsafe_code)]是 crate 级别的 lint 属性任何引入unsafe代码的改动都会在编译期被拒绝——这是 axum 的一项硬性安全承诺。八、MSRV 与版本现状Minimum Supported Rust Versionaxum 的 MSRV最低支持 Rust 版本为1.80见 README「Minimum supported Rust version」一节。如果你的工具链低于此版本需要先升级。版本演进提示Breaking changesREADME 特别以警告块提示We are currently working towards axum 0.9 so themainbranch contains breaking changes. See the0.8.xbranch for whats released to crates.io.也就是说仓库main分支正在向 0.9 演进main 分支包含破坏性变更发布到 crates.io 的稳定版本以 0.8.x 为准。当前 axum/Cargo.toml 中的版本号为0.8.9。使用 crates.io 版本的用户不会受影响但如果你直接依赖本仓库 main 分支需要留意破坏性变更。完整的演进记录可查看 axum/CHANGELOG.md。九、feature flags按需裁剪依赖axum 通过一套 feature flags 来控制编译内容与可选依赖axum/Cargo.toml 中给出了完整定义其目的是减少编译量与可选依赖。下表整理自 axum/src/lib.rs 的「Feature flags」一节Feature说明是否默认开启http1启用 hyper 的http1特性✔http2启用 hyper 的http2特性json启用Json类型及相关便捷功能✔macros启用可选工具宏如#[derive(FromRef)]、debug_handlermatched-path捕获每个请求的路由路径提供MatchedPath提取器✔multipart用Multipart解析multipart/form-data请求original-uri捕获每个请求的原始 URI提供OriginalUri提取器✔tokio引入 tokio 依赖启用axum::serve、SSE 与extract::connect_info类型✔tower-log启用 tower 的log特性✔tracing记录内置提取器的拒绝rejection日志✔ws通过extract::ws提供 WebSocket 支持form启用Form提取器✔query启用Query提取器✔默认特性集合在 axum/Cargo.toml 中定义为form、http1、json、matched-path、original-uri、query、tokio、tower-log、tracing。需要 HTTP/2、WebSocket 或 multipart 时在Cargo.toml中追加对应特性即可例如[dependencies] axum { version 0.8, features [http2, ws, multipart, macros] }十、示例与生态配套丰富的示例目录README 指出仓库 examples 目录包含大量「如何组合使用 axum」的示例涵盖基础类hello-world、todos、key-value-store、versioning集成类sqlx-postgres、diesel-async-postgres、mongodb、tokio-redis、tokio-postgres、async-graphql、jwt、oauth协议与传输类websockets、websockets-http2、sse、unix-domain-socket、tls-rustls、low-level-rustls / openssl / native-tls、serve-with-hyper、http-proxy、reverse-proxy工程实践类testing、testing-websockets、tracing-aka-logging、prometheus-metrics、request-id、graceful-shutdown、tls-graceful-shutdown、templates / templates-minijinja、static-file-server、compression、cors、validator、customize-extractor-error、customize-path-rejection 等。每个示例目录都带有独立的 Cargo.toml 与src/main.rs可以用cargo run -p example-名称的方式直接运行工作区级依赖见 examples/Cargo.toml。配套 crate 与文档axum-coreaxum-core/README.md包含核心类型与 trait。README 及 axum/src/lib.rs 的「Building integrations for axum」一节建议库作者若要为FromRequest、FromRequestParts、IntoResponse提供实现应优先依赖axum-core而非axum因为它更稳定、更不易发生破坏性变更axum-extraaxum-extra/README.md提供typed-header、ErasedJson、Cached、cookie 等额外提取器/响应类型axum-macrosaxum-macros/README.md提供#[debug_handler]、#[derive(FromRef)]、#[derive(FromRequest)]、#[derive(TypedPath)]等过程宏其测试用例覆盖了大量编译期错误场景见 axum-macros/tests 目录。十一、参与贡献与许可证README 欢迎开发者通过 CONTRIBUTING.md 了解贡献流程。项目采用MIT 许可证见 axum/LICENSE并且有一条明确的贡献条款Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion inaxumby you, shall be licensed as MIT, without any additional terms or conditions.即除非贡献者明确另行声明否则为 axum 提交的贡献默认按 MIT 许可不附加额外条款或条件。小结通过 axum/README.md 我们可以清晰地看到 axum 的设计主线以tower::Service为统一的中间件与协议抽象以宏无关的RouterAPI 组织路由以 Handler Extractor IntoResponse 三个抽象覆盖请求处理全链路以 hyper 为底层运行时获得接近原生的性能并以#![forbid(unsafe_code)]提供 100% Safe Rust 的安全承诺。无论你是想快速搭建一个带 JSON 接口的服务还是需要深度定制中间件、共享状态、WebSocket 或 gRPC 互通axum 都能以模块化的方式组合出你需要的结构。仓库中 examples 目录下数十个可运行示例与 axum/src/lib.rs 的详尽 crate 文档是继续深入学习的下一步最佳入口。【免费下载链接】axumHTTP routing and request-handling library for Rust that focuses on ergonomics and modularity项目地址: https://gitcode.com/GitHub_Trending/ax/axum创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考