Axum是Tokio团队开发的Web框架,以类型安全和高性能著称。本课将构建一个完整的RESTful API服务。
// Cargo.toml:
// [dependencies]
// axum = "0.8"
// tokio = { version = "1", features = ["full"] }
// serde = { version = "1", features = ["derive"] }
// serde_json = "1"
// 概念演示(不依赖tokio运行时)
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
struct Todo {
id: u64,
title: String,
completed: bool,
}
struct TodoStore {
todos: HashMap<u64, Todo>,
next_id: u64,
}
impl TodoStore {
fn new() -> Self { TodoStore { todos: HashMap::new(), next_id: 1 } }
fn create(&mut self, title: String) -> &Todo {
let id = self.next_id;
self.next_id += 1;
let todo = Todo { id, title, completed: false };
self.todos.insert(id, todo);
self.todos.get(&id).unwrap()
}
fn get(&self, id: u64) -> Option<&Todo> { self.todos.get(&id) }
fn list(&self) -> Vec<&Todo> { self.todos.values().collect() }
fn toggle(&mut self, id: u64) -> Option<&Todo> {
if let Some(todo) = self.todos.get_mut(&id) {
todo.completed = !todo.completed;
Some(self.todos.get(&id).unwrap())
} else { None }
}
fn delete(&mut self, id: u64) -> bool { self.todos.remove(&id).is_some() }
}
fn main() {
let mut store = TodoStore::new();
// 模拟API请求
let t1 = store.create("学习Rust".to_string());
let t2 = store.create("构建Web服务".to_string());
let t3 = store.create("写文档".to_string());
println!("📋 所有TODO:");
for todo in store.list() {
println!(" [{}] {} (id={})", if todo.completed {"✅"} else {"⬜"}, todo.title, todo.id);
}
// 切换完成状态
store.toggle(1);
println!("\n切换后:");
for todo in store.list() {
println!(" [{}] {}", if todo.completed {"✅"} else {"⬜"}, todo.title);
}
// 删除
store.delete(3);
println!("\n删除后剩余{}项", store.list().len());
// Axum路由概念
println!("\n=== Axum路由结构 ===");
println!("GET /api/todos → 列出所有");
println!("POST /api/todos → 创建新项");
println!("GET /api/todos/:id → 获取单个");
println!("PUT /api/todos/:id → 更新");
println!("DELETE /api/todos/:id → 删除");
}
✅ 验证通过
创建Axum项目,实现GET /和POST /echo路由。
实现请求日志中间件,记录每个请求的方法、路径和耗时。
// REST API设计原则
// GET /api/tasks - 列出
// POST /api/tasks - 创建
// PUT /api/tasks/:id - 更新
// DELETE /api/tasks/:id - 删除
// 中间件概念
fn logging_middleware(method: &str, path: &str, status: u16, elapsed_ms: u64) {
println!("[{}] {} → {} ({}ms)", method, path, status, elapsed_ms);
}
fn main() {
logging_middleware("GET", "/api/tasks", 200, 5);
logging_middleware("POST", "/api/tasks", 201, 12);
logging_middleware("GET", "/api/tasks/999", 404, 2);
println!("
Axum中间件:");
println!(" use axum::middleware;");
println!(" let app = Router::new()");
println!(" .route("/api", get(handler))");
println!(" .layer(middleware::from_fn(log_middleware));");
}
✅ 验证通过
fn main() {
println!("Rust Web服务部署选项:");
println!();
println!("1. 独立二进制部署:");
println!(" cargo build --release");
println!(" ./target/release/myserver");
println!(" // 单文件部署,无需运行时!");
println!();
println!("2. Docker部署:");
println!(" FROM rust:1.95 AS builder");
println!(" WORKDIR /app");
println!(" COPY . .");
println!(" RUN cargo build --release");
println!(" ");
println!(" FROM debian:bookworm-slim");
println!(" COPY --from=builder /app/target/release/myserver /");
println!(" CMD ["./myserver"]");
println!();
println!("3. Systemd服务:");
println!(" [Unit]");
println!(" Description=My Rust Server");
println!(" [Service]");
println!(" ExecStart=/usr/local/bin/myserver");
println!(" Restart=always");
println!();
println!("性能基准:");
println!(" Axum: ~300k req/s (hello world)");
println!(" Actix: ~400k req/s (hello world)");
println!(" Node: ~50k req/s (hello world)");
println!(" Go: ~200k req/s (hello world)");
}
use std::collections::HashMap;
#[derive(Debug, Clone)]
struct Task { id: u64, title: String, done: bool }
struct ApiServer { tasks: HashMap, next_id: u64 }
impl ApiServer {
fn new() -> Self { ApiServer { tasks: HashMap::new(), next_id: 1 } }
fn list(&self) -> Vec<&Task> { self.tasks.values().collect() }
fn create(&mut self, title: &str) -> &Task {
let id = self.next_id; self.next_id += 1;
let t = Task { id, title: title.into(), done: false };
self.tasks.insert(id, t); self.tasks.get(&id).unwrap()
}
fn get(&self, id: u64) -> Option<&Task> { self.tasks.get(&id) }
fn update(&mut self, id: u64, title: Option<&str>, done: Option) -> Option<&Task> {
let t = self.tasks.get_mut(&id)?;
if let Some(s) = title { t.title = s.into(); }
if let Some(d) = done { t.done = d; }
Some(self.tasks.get(&id).unwrap())
}
fn delete(&mut self, id: u64) -> bool { self.tasks.remove(&id).is_some() }
}
fn main() {
let mut api = ApiServer::new();
api.create("学习Axum"); api.create("写API"); api.create("部署上线");
api.update(1, None, Some(true));
println!("GET /api/tasks:");
for t in api.list() { println!(" [{}] {} (id={})", if t.done{"✅"}else{"⬜"}, t.title, t.id); }
println!("
GET /api/tasks/2:");
if let Some(t) = api.get(2) { println!(" {} (done={})", t.title, t.done); }
api.delete(3);
println!("
DELETE /api/tasks/3 后剩余{}项", api.list().len());
}
✅ 验证通过
// Cargo.toml:
// axum = "0.8"
// tokio = { version = "1", features = ["full"] }
// serde = { version = "1", features = ["derive"] }
// serde_json = "1"
// tower-http = { version = "0.6", features = ["cors", "trace"] }
// tracing = "0.1"
// tracing-subscriber = "0.3"
// sqlx = { version = "0.8", features = ["postgres", "runtime-tokio"] }
//
// 项目结构:
// src/
// ├── main.rs - 入口+路由
// ├── handlers/ - 请求处理器
// ├── models/ - 数据模型
// ├── services/ - 业务逻辑
// ├── repositories/ - 数据访问
// └── config.rs - 配置管理
fn main() {
println!("Axum项目架构:");
println!(" src/main.rs - 服务器启动+路由");
println!(" src/handlers/ - HTTP处理器");
println!(" src/models/ - 数据模型(DTO)");
println!(" src/services/ - 业务逻辑层");
println!(" src/repositories/ - 数据访问层");
println!(" src/config.rs - 配置管理");
println!(" src/middleware/ - 中间件");
println!(" src/errors.rs - 错误类型");
println!("
性能数据:");
println!(" 单机: 30万+ req/s (hello world)");
println!(" 延迟: <100μs (本地)");
println!(" 内存: <10MB (空闲)");
}
use std::collections::HashMap;
use std::time::Instant;
struct Request { method: String, path: String, headers: HashMap, body: Option }
struct Response { status: u16, body: String }
impl Response { fn ok(body: &str) -> Self { Response { status: 200, body: body.into() } } fn not_found() -> Self { Response { status: 404, body: "Not Found".into() } } fn json(body: &str) -> Self { Response { status: 200, body: body.into() } } }
type Handler = fn(Request) -> Response;
type Middleware = fn(&Request, &Response, u64);
struct App {
routes: HashMap,
middlewares: Vec,
}
impl App {
fn new() -> Self { App { routes: HashMap::new(), middlewares: Vec::new() } }
fn route(mut self, key: &str, handler: Handler) -> Self { self.routes.insert(key.into(), handler); self }
fn middleware(mut self, m: Middleware) -> Self { self.middlewares.push(m); self }
fn handle(&self, req: Request) -> Response {
let key = format!("{} {}", req.method, req.path);
let start = Instant::now();
let resp = self.routes.get(&key).map(|h| h(req)).unwrap_or_else(Response::not_found);
let elapsed = start.elapsed().as_millis() as u64;
for m in &self.middlewares { m(&Request{method:String::new(),path:String::new(),headers:HashMap::new(),body:None}, &resp, elapsed); }
resp
}
}
fn log_middleware(_req: &Request, resp: &Response, ms: u64) { println!("[LOG] {} ({}ms)", resp.status, ms); }
fn index(_req: Request) -> Response { Response::ok("Welcome!") }
fn api_health(_req: Request) -> Response { Response::json("{"status":"ok"}") }
fn main() {
let app = App::new()
.route("GET /", index)
.route("GET /api/health", api_health)
.middleware(log_middleware);
println!("GET / → {}", app.handle(Request{method:"GET".into(),path:"/".into(),headers:HashMap::new(),body:None}).status);
println!("GET /api/health → {}", app.handle(Request{method:"GET".into(),path:"/api/health".into(),headers:HashMap::new(),body:None}).body);
}
✅ 验证通过
Rust的设计哲学贯穿始终:安全、并发、高性能。每个特性都是这三个目标的具体体现。本课所学内容是构建真实Rust应用的基石,务必在实践中反复练习巩固。
记住:Rust的学习曲线虽陡,但一旦掌握,你将获得前所未有的编程信心——编译器就是你的最佳队友。
// Axum核心类型:
// Router<S> - 路由器
// MethodRouter - 方法路由(GET/POST/PUT/DELETE)
// Handler - 处理器trait
// FromRequest - 提取器trait
// IntoResponse - 响应trait
// State<S> - 状态提取器
// Extension<T> - 扩展提取器
// 常用提取器:
// axum::extract::Path<T> - 路径参数
// axum::extract::Query<T> - 查询参数
// axum::extract::Json<T> - JSON请求体
// axum::extract::Form<T> - 表单数据
// axum::extract::State<S> - 共享状态
// axum::extract::Extension - 请求扩展
// axum::extract::OriginalUri - 原始URI
// axum::extract::ConnectInfo - 连接信息
// 常用响应:
// axum::Json<T> - JSON响应
// axum::response::Html - HTML响应
// axum::response::Redirect - 重定向
// impl IntoResponse - 自定义响应
// StatusCode - 状态码
// axum::response::AppendHeaders - 追加头
fn main() {
println!("Axum路由示例:");
println!(" .route("/", get(handler))");
println!(" .route("/users", post(create_user))");
println!(" .route("/users/:id", get(get_user))");
println!(" .route("/users/:id", put(update_user))");
println!(" .route("/users/:id", delete(delete_user))");
println!("
中间件:");
println!(" tower-http::trace::TraceLayer");
println!(" tower-http::cors::CorsLayer");
println!(" tower-http::limit::RateLimitLayer");
println!(" tower-http::timeout::TimeoutLayer");
println!(" tower-http::compression::CompressionLayer");
println!("
状态管理:");
println!(" Arc<Mutex<State>> - 简单共享");
println!(" Arc<RwLock<State>> - 读写锁");
println!(" Arc<DbPool> - 数据库连接池");
}