5 分钟搭好开发环境:Rust + Axum 项目从零开始
5 分钟搭好开发环境Rust Axum 项目从零开始摘要从 Rust 工具链安装到启动第一个 Axum Web 服务手把手教学。涵盖 Cargo.toml 依赖配置、Router/Extractor/Middleware/State 四大核心概念、项目分层架构设计、cargo-watch 热加载开发附完整可运行代码。一、安装 Rust 全家桶Linux / macOScurl--protohttps--tlsv1.2-sSfhttps://sh.rustup.rs|shsource~/.cargo/envWindows下载 rustup-init.exe一路 Next。验证安装$ rustc--versionrustc1.85.0(4d91de4c42025-02-17)$cargo--versioncargo1.85.0(d73d2caf92025-01-15)配置国内镜像中国大陆用户编辑~/.cargo/config.toml[source.crates-io] replace-with ustc [source.ustc] registry sparsehttps://mirrors.ustc.edu.cn/crates.io-index/IDE 推荐VS Coderust-analyzer插件免费首选RustRoverJetBrains功能最强Zed新一代高性能编辑器二、项目初始化cargonew nexus-opscdnexus-ops生成的结构nexus-ops/ ├── Cargo.toml # 项目元数据 依赖 └── src/ └── main.rs # 入口点编辑Cargo.toml[package] name nexus-ops version 0.1.0 edition 2021 [dependencies] # Web 框架 axum 0.7 # 异步运行时 tokio { version 1, features [full] } # JSON 序列化 serde { version 1, features [derive] } serde_json 1 # 日志 tracing 0.1 tracing-subscriber { version 0.3, features [env-filter] } # 静态文件 CORS tower-http { version 0.5, features [cors, fs] }三、第一个 Axum 应用// src/main.rsuseaxum::{Router,routing::get,response::Json,extract::Path,};useserde::Serialize;usestd::net::SocketAddr;usetower_http::services::ServeDir;usetracing_subscriber;#[derive(Serialize)]structApiResponseT:Serialize{success:bool,data:OptionT,error:OptionString,}#[derive(Serialize)]structHealthInfo{status:String,version:String,uptime_seconds:u64,}/// GET /api/health — 健康检查asyncfnhealth_check()-JsonApiResponseHealthInfo{Json(ApiResponse{success:true,data:Some(HealthInfo{status:healthy.into(),version:env!(CARGO_PKG_VERSION).into(),uptime_seconds:0,}),error:None,})}/// GET /api/devices/:id — 获取单个设备asyncfnget_device(Path(id):Pathi64)-JsonApiResponseString{Json(ApiResponse{success:true,data:Some(format!(Device #{},id)),error:None,})}/// GET / — 首页重定向asyncfnindex()-staticstr{NexusOps API Server is running.\n}#[tokio::main]asyncfnmain(){// 初始化日志tracing_subscriber::fmt().with_env_filter(nexus_opsinfo,tower_httpinfo).init();// 构建路由letappRouter::new().route(/,get(index)).route(/api/health,get(health_check)).route(/api/devices/:id,get(get_device)).nest_service(/static,ServeDir::new(static)).fallback(||async{404 Not Found});// 绑定并启动letaddrSocketAddr::from(([0,0,0,0],8080));tracing::info!(NexusOps server listening on http://{},addr);letlistenertokio::net::TcpListener::bind(addr).await.unwrap();axum::serve(listener,app).await.unwrap();}运行cargorun# 输出# 2026-05-07T10:00:00.000Z INFO nexus_ops: NexusOps server listening on http://0.0.0.0:8080测试# 健康检查$curlhttp://localhost:8080/api/health|jq{success:true,data:{status:healthy,version:0.1.0,uptime_seconds:0},error:null}# 路径参数$curlhttp://localhost:8080/api/devices/42{success:true,data:Device #42,error:null}四、Axum 四大核心概念1. Router路由器letappRouter::new().route(/api/health,get(health_check))// GET 请求.route(/api/devices,post(create_device))// POST 请求.route(/api/devices/:id,get(get_device)// 路径参数.delete(delete_device))// 链式组合.nest(/api/v2,v2_router)// 嵌套路由.merge(another_router)// 合并路由.fallback(fallback_handler);// 404 处理2. Extractor提取器useaxum::{extract::{Path,Query,State,Json},http::StatusCode,};// 路径参数: /api/devices/42asyncfnhandler(Path(id):Pathi64){}// 查询参数: /api/devices?page1size20#[derive(Deserialize)]structPagination{page:Optioni64,size:Optioni64}asyncfnhandler(Query(p):QueryPagination){}// JSON 请求体#[derive(Deserialize)]structCreateDeviceReq{name:String,ip:String}asyncfnhandler(Json(req):JsonCreateDeviceReq){}// 应用状态asyncfnhandler(State(state):StateArcAppState){}// 组合使用asyncfncreate_device(State(state):StateArcAppState,Json(req):JsonCreateDeviceReq,)-ResultJsonDevice,StatusCode{// 验证、存储、返回}3. State共享状态usestd::sync::Arc;userusqlite::Connection;pubstructAppState{pubdb:Connection,// 后面会加入更多: plugin_registry, alert_engine, ...}#[tokio::main]asyncfnmain(){letstateArc::new(AppState{db:init_database(),});letappRouter::new().route(/api/devices,get(list_devices)).with_state(state);// ...}// 在 handler 中访问数据库asyncfnlist_devices(State(state):StateArcAppState,)-JsonVecDevice{letdevicesDeviceRepo::list(state.db);Json(devices)}4. Middleware中间件useaxum::middleware;usetower_http::cors::{CorsLayer,Any};letappRouter::new()// CORS.layer(CorsLayer::permissive())// 请求日志.layer(tower_http::trace::TraceLayer::new_for_http())// 自定义鉴权中间件.layer(middleware::from_fn(auth_middleware));五、项目分层架构从单文件演进到模块化结构src/ ├── main.rs # 入口初始化 启动 ├── handlers/ # 请求处理层 │ ├── mod.rs │ ├── health.rs # 健康检查 │ └── device.rs # 设备 CRUD ├── models/ # 数据模型 │ ├── mod.rs │ ├── device.rs # 设备 struct │ └── api.rs # 统一响应格式 ├── database/ # 数据库层 │ ├── mod.rs │ ├── migration.rs # 迁移系统 │ └── device_repo.rs # 设备数据访问 └── server/ ├── mod.rs └── routes.rs # 路由集中注册server/routes.rs— 所有路由集中管理useaxum::{Router,middleware};usestd::sync::Arc;usecrate::handlers;usecrate::models::AppState;pubfnbuild_router(state:ArcAppState)-Router{Router::new().route(/api/health,get(handlers::health::check)).route(/api/devices,get(handlers::device::list).post(handlers::device::create)).route(/api/devices/:id,get(handlers::device::get).put(handlers::device::update).delete(handlers::device::delete)).with_state(state)}main.rs— 入口极简#[tokio::main]asyncfnmain(){tracing_subscriber::fmt().init();letstateArc::new(AppState{db:database::init(),});letappserver::routes::build_router(state);letlistenertokio::net::TcpListener::bind(0.0.0.0:8080).await.unwrap();tracing::info!(Server listening on 0.0.0.0:8080);axum::serve(listener,app).await.unwrap();}六、开发效率工具cargo-watch 热加载cargoinstallcargo-watch# 文件变更自动重启cargowatch-xrun# 仅监听 src 目录cargowatch-wsrc-xrun日志调试# 设置日志级别RUST_LOGnexus_opsdebugcargorun# 按模块过滤RUST_LOGnexus_opsinfo,axumdebugcargorun七、常见问题Q: 编译太慢怎么办# 使用 mold 链接器Linuxcargoinstallmold# 在 .cargo/config.toml 添加[target.x86_64-unknown-linux-gnu]linkerclangrustflags[-C,link-arg-fuse-ldmold]Q: macOS 上编译报错xcode-select--install# 安装命令行工具本期要点Rust 工具链安装 国内镜像配置Axum 四大核心概念Router / Extractor / State / Middleware60 行代码启动一个完整的 Web 服务项目分层架构handlers / models / database / servercargo-watch 热加载开发下一期预告《SQLite 数据库设计实战设备模型的抽象艺术》——手写数据库迁移系统、设备/接口/IP 三表设计、rusqlite 最佳实践。完整代码git clone后git checkout series-ep-02环境Rust 1.85, Linux/macOS/Windows