Rust Actix Web 项目实战教程:构建用户管理系统
项目概述
本教程将指导你使用 Rust 和 Actix Web 构建一个完整的用户管理系统,包括数据库交互、Redis 缓存和 Swagger UI 文档。
技术栈
- Rust 编程语言
- Actix Web 框架
- SQLx (MySQL 数据库)
- Redis 缓存
- Utoipa (OpenAPI 文档)
- Dotenv (环境变量管理)
项目结构
actix_web_project/
├── Cargo.toml
├── .env
├── src/
│ ├── main.rs # 应用入口
│ ├── models.rs # 数据模型
│ ├── routes.rs # API 路由处理
│ ├── state.rs # 应用状态管理
│ └── docs.rs # OpenAPI 文档
└── setup_database.sql # 数据库初始化脚本
准备工作
1. 安装依赖
确保你已安装:
- Rust (https://rustup.rs/)
- MySQL
- Redis
2. 创建项目
cargo new actix_web_project
cd actix_web_project
3. 配置 Cargo.toml
[dependencies]
actix-web = "4.9.0"
sqlx = { version = "0.7.4", features = ["mysql", "runtime-tokio"] }
redis = { version = "0.24", features = ["tokio-comp"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
dotenv = "0.15"
utoipa = { version = "5.3.1", features = ["actix_extras"] }
utoipa-swagger-ui = { version = "9.0.0", features = ["actix-web"] }
4. 数据库设置
创建 setup_database.sql
:
CREATE DATABASE user_management;
USE user_management;
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL
);
INSERT INTO users (name, email) VALUES
('张三', '[email protected]'),
('李四', '[email protected]');
5. 环境变量 (.env)
DATABASE_URL=mysql://username:password@localhost/user_management
REDIS_URL=redis://127.0.0.1:6379
代码实现
models.rs
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct User {
pub id: i32,
pub name: String,
pub email: String,
}
state.rs
use sqlx::mysql::MySqlPool;
use redis::Client as RedisClient;
pub struct AppState {
pub db: MySqlPool,
pub redis_client: RedisClient,
}
routes.rs
use actix_web::{get, post, web, HttpResponse, Responder};
use serde_json::json;
use redis::AsyncCommands;
use crate::{
models::User,
state::AppState,
};
#[utoipa::path(
get,
path = "/users",
responses(
(status = 200, description = "成功获取用户列表", body = [User])
)
)]
#[get("/users")]
pub async fn get_all_users(data: web::Data<AppState>) -> impl Responder {
let pool = &data.db;
let query_result = sqlx::query_as!(
User,
r#"SELECT id, name, email FROM users"#
)
.fetch_all(pool)
.await;
match query_result {
Ok(users) => HttpResponse::Ok().json(users),
Err(_) => HttpResponse::InternalServerError().body("获取用户时出错"),
}
}
docs.rs
use utoipa::OpenApi;
use crate::models::User;
#[derive(OpenApi)]
#[openapi(
paths(
crate::routes::get_all_users
),
components(
schemas(User)
)
)]
pub struct ApiDoc;
main.rs
use actix_web::{App, HttpServer, web};
use sqlx::mysql::MySqlPool;
use redis::Client as RedisClient;
use std::env;
use utoipa_swagger_ui::SwaggerUi;
use dotenv::dotenv;
use utoipa::OpenApi;
mod models;
mod routes;
mod state;
mod docs;
use routes::get_all_users;
use state::AppState;
use docs::ApiDoc;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
dotenv().ok();
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL 必须设置");
let pool = MySqlPool::connect(&database_url).await.expect("创建连接池失败");
let redis_url = env::var("REDIS_URL").expect("REDIS_URL 必须设置");
let redis_client = RedisClient::open(redis_url).expect("创建 Redis 客户端失败");
println!("服务器运行在 http://127.0.0.1:8880");
println!("swagger-ui: http://127.0.0.1:8880/swagger-ui/");
HttpServer::new(move || {
App::new()
.app_data(web::Data::new(AppState {
db: pool.clone(),
redis_client: redis_client.clone(),
}))
.service(get_all_users)
.service(
SwaggerUi::new("/swagger-ui/{_:.*}")
.url("/api-doc/openapi.json", ApiDoc::openapi())
)
})
.bind(("127.0.0.1", 8880))?
.run()
.await
}
运行项目
- 初始化数据库
- 设置 .env 文件
- 启动 Redis
- 运行项目
cargo run
访问 Swagger UI
打开浏览器,访问:
http://127.0.0.1:8880/swagger-ui/
进阶练习
- 添加更多 CRUD 操作
- 实现用户认证
- 添加错误处理中间件
- 编写单元测试和集成测试