- 创建 Cargo.toml 配置文件,包含所有必要依赖 - 建立完整的项目模块结构(config, models, handlers, routes, services, storage, middleware, utils) - 实现用户数据模型和内存存储 - 创建基础的 HTTP 处理器和路由配置 - 添加错误处理和 JWT 认证中间件 - 配置环境变量和日志系统 - 创建项目文档和学习指南 - 服务器可以成功编译和启动
381 lines
8.6 KiB
Markdown
381 lines
8.6 KiB
Markdown
# Rust REST API 学习指南
|
||
|
||
## 学习前准备
|
||
|
||
### 必备知识
|
||
- Rust 基础语法(所有权、借用、生命周期)
|
||
- 基本的 HTTP 协议知识
|
||
- REST API 设计原则
|
||
- JSON 数据格式
|
||
|
||
### 开发环境
|
||
- Rust 1.70+
|
||
- VS Code 或其他 IDE
|
||
- Postman 或 curl(API 测试)
|
||
- Git(版本控制)
|
||
|
||
## 详细学习路径
|
||
|
||
### 第一周:基础搭建(阶段 1-2)
|
||
|
||
#### 学习目标
|
||
- 掌握 Cargo 项目管理
|
||
- 理解 Axum 框架基础
|
||
- 学会创建基本的 HTTP 服务
|
||
|
||
#### 关键概念
|
||
1. **Cargo.toml 配置**
|
||
- 依赖管理和版本控制
|
||
- 特性(features)选择
|
||
- 开发依赖 vs 运行时依赖
|
||
|
||
2. **异步编程基础**
|
||
- `async/await` 语法
|
||
- Tokio 运行时
|
||
- Future 和 Task 概念
|
||
|
||
3. **Axum 框架核心**
|
||
- Router 和路由定义
|
||
- 处理器函数(Handler)
|
||
- 响应类型和状态码
|
||
|
||
#### 实践练习
|
||
```rust
|
||
// 练习1: 创建健康检查端点
|
||
async fn health() -> Json<Value> {
|
||
Json(json!({
|
||
"status": "ok",
|
||
"timestamp": Utc::now(),
|
||
"uptime": "1h 30m"
|
||
}))
|
||
}
|
||
|
||
// 练习2: 添加版本信息端点
|
||
async fn version() -> Json<Value> {
|
||
Json(json!({
|
||
"version": env!("CARGO_PKG_VERSION"),
|
||
"name": env!("CARGO_PKG_NAME")
|
||
}))
|
||
}
|
||
```
|
||
|
||
#### 常见问题和解决方案
|
||
- **编译错误**: 检查依赖版本兼容性
|
||
- **异步函数理解**: 从同步思维转向异步思维
|
||
- **模块导入**: 理解 Rust 的模块系统
|
||
|
||
---
|
||
|
||
### 第二周:数据模型和存储(阶段 3-4)
|
||
|
||
#### 学习目标
|
||
- 掌握 Serde 序列化
|
||
- 理解内存存储设计
|
||
- 实现完整的 CRUD 操作
|
||
|
||
#### 关键概念
|
||
1. **数据建模**
|
||
- 结构体设计原则
|
||
- 序列化和反序列化
|
||
- 类型转换和 From trait
|
||
|
||
2. **并发安全**
|
||
- `Arc<RwLock<T>>` 模式
|
||
- 读写锁的使用场景
|
||
- 线程安全的数据共享
|
||
|
||
3. **HTTP 方法映射**
|
||
- GET, POST, PUT, DELETE
|
||
- RESTful 设计原则
|
||
- 路径参数提取
|
||
|
||
#### 实践练习
|
||
```rust
|
||
// 练习1: 扩展用户模型
|
||
#[derive(Debug, Serialize, Deserialize)]
|
||
pub struct User {
|
||
pub id: Uuid,
|
||
pub username: String,
|
||
pub email: String,
|
||
pub profile: UserProfile,
|
||
pub status: UserStatus,
|
||
}
|
||
|
||
#[derive(Debug, Serialize, Deserialize)]
|
||
pub struct UserProfile {
|
||
pub first_name: String,
|
||
pub last_name: String,
|
||
pub bio: Option<String>,
|
||
}
|
||
|
||
// 练习2: 实现用户搜索
|
||
pub async fn search_users(
|
||
State(store): State<MemoryUserStore>,
|
||
Query(params): Query<SearchParams>,
|
||
) -> Json<Vec<UserResponse>> {
|
||
// 实现按用户名或邮箱搜索
|
||
}
|
||
```
|
||
|
||
#### 调试技巧
|
||
- 使用 `println!` 和 `dbg!` 宏调试
|
||
- 理解借用检查器错误信息
|
||
- 使用 Postman 测试 API 端点
|
||
|
||
---
|
||
|
||
### 第三周:错误处理和验证(阶段 5)
|
||
|
||
#### 学习目标
|
||
- 掌握 Rust 错误处理模式
|
||
- 实现请求数据验证
|
||
- 创建统一的错误响应
|
||
|
||
#### 关键概念
|
||
1. **错误处理哲学**
|
||
- `Result<T, E>` 类型
|
||
- `?` 操作符的使用
|
||
- 错误传播和转换
|
||
|
||
2. **自定义错误类型**
|
||
- 枚举定义错误类型
|
||
- `IntoResponse` trait 实现
|
||
- 错误信息的用户友好化
|
||
|
||
3. **数据验证**
|
||
- 输入验证策略
|
||
- 自定义验证规则
|
||
- 验证错误的处理
|
||
|
||
#### 实践练习
|
||
```rust
|
||
// 练习1: 扩展错误类型
|
||
#[derive(Debug)]
|
||
pub enum ApiError {
|
||
ValidationError(ValidationErrors),
|
||
DatabaseError(String),
|
||
NotFound(String),
|
||
Conflict(String),
|
||
Unauthorized,
|
||
Forbidden,
|
||
}
|
||
|
||
// 练习2: 实现自定义验证器
|
||
fn validate_username(username: &str) -> Result<(), ValidationError> {
|
||
if username.len() < 3 {
|
||
return Err(ValidationError::new("Username too short"));
|
||
}
|
||
if username.contains(' ') {
|
||
return Err(ValidationError::new("Username cannot contain spaces"));
|
||
}
|
||
Ok(())
|
||
}
|
||
```
|
||
|
||
#### 最佳实践
|
||
- 永远不要 `unwrap()` 在生产代码中
|
||
- 提供有意义的错误信息
|
||
- 区分内部错误和用户错误
|
||
|
||
---
|
||
|
||
### 第四周:身份认证(阶段 6)
|
||
|
||
#### 学习目标
|
||
- 理解 JWT 工作原理
|
||
- 实现中间件模式
|
||
- 掌握安全编程基础
|
||
|
||
#### 关键概念
|
||
1. **JWT 认证流程**
|
||
- Token 生成和验证
|
||
- Claims 和 Payload
|
||
- 安全密钥管理
|
||
|
||
2. **中间件设计**
|
||
- 请求拦截和处理
|
||
- 状态传递机制
|
||
- 条件性中间件应用
|
||
|
||
3. **安全考虑**
|
||
- 密码哈希(bcrypt)
|
||
- Token 过期处理
|
||
- HTTPS 和安全头
|
||
|
||
#### 实践练习
|
||
```rust
|
||
// 练习1: 实现角色基础访问控制
|
||
#[derive(Debug, Serialize, Deserialize)]
|
||
pub enum UserRole {
|
||
Admin,
|
||
User,
|
||
Guest,
|
||
}
|
||
|
||
pub async fn admin_only_middleware(
|
||
claims: Claims,
|
||
req: Request,
|
||
next: Next,
|
||
) -> Result<Response, StatusCode> {
|
||
if claims.role != UserRole::Admin {
|
||
return Err(StatusCode::FORBIDDEN);
|
||
}
|
||
Ok(next.run(req).await)
|
||
}
|
||
|
||
// 练习2: 实现刷新 Token 机制
|
||
pub async fn refresh_token(
|
||
State(store): State<MemoryUserStore>,
|
||
RequestJson(payload): RequestJson<RefreshTokenRequest>,
|
||
) -> Result<Json<TokenResponse>, ApiError> {
|
||
// 验证刷新 token 并生成新的访问 token
|
||
}
|
||
```
|
||
|
||
#### 安全检查清单
|
||
- [ ] 使用强密码哈希算法
|
||
- [ ] 实现 Token 过期机制
|
||
- [ ] 验证所有输入数据
|
||
- [ ] 记录安全相关事件
|
||
|
||
---
|
||
|
||
### 第五周:测试和文档(阶段 7)
|
||
|
||
#### 学习目标
|
||
- 编写全面的测试套件
|
||
- 创建清晰的 API 文档
|
||
- 掌握测试驱动开发
|
||
|
||
#### 关键概念
|
||
1. **测试策略**
|
||
- 单元测试 vs 集成测试
|
||
- 测试数据管理
|
||
- Mock 和 Stub 技术
|
||
|
||
2. **API 测试**
|
||
- HTTP 客户端测试
|
||
- 异步测试编写
|
||
- 测试环境隔离
|
||
|
||
3. **文档编写**
|
||
- OpenAPI/Swagger 规范
|
||
- 代码注释最佳实践
|
||
- 示例和用例
|
||
|
||
#### 实践练习
|
||
```rust
|
||
// 练习1: 编写完整的用户 CRUD 测试
|
||
#[tokio::test]
|
||
async fn test_user_lifecycle() {
|
||
let app = create_test_app().await;
|
||
|
||
// 创建用户
|
||
let user = create_test_user(&app, "testuser").await;
|
||
assert_eq!(user.username, "testuser");
|
||
|
||
// 获取用户
|
||
let fetched_user = get_user(&app, user.id).await;
|
||
assert_eq!(fetched_user.id, user.id);
|
||
|
||
// 更新用户
|
||
let updated_user = update_user(&app, user.id, "newname").await;
|
||
assert_eq!(updated_user.username, "newname");
|
||
|
||
// 删除用户
|
||
delete_user(&app, user.id).await;
|
||
assert!(get_user(&app, user.id).await.is_err());
|
||
}
|
||
|
||
// 练习2: 性能测试
|
||
#[tokio::test]
|
||
async fn test_concurrent_user_creation() {
|
||
let app = create_test_app().await;
|
||
let mut handles = vec![];
|
||
|
||
for i in 0..100 {
|
||
let app_clone = app.clone();
|
||
let handle = tokio::spawn(async move {
|
||
create_test_user(&app_clone, &format!("user{}", i)).await
|
||
});
|
||
handles.push(handle);
|
||
}
|
||
|
||
let results = futures::future::join_all(handles).await;
|
||
assert_eq!(results.len(), 100);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 第六周及以后:高级功能(阶段 8-12)
|
||
|
||
#### 数据库集成(阶段 8-9)
|
||
- SQLite 和 PostgreSQL 集成
|
||
- ORM 选择(Diesel vs SQLx)
|
||
- 数据库迁移管理
|
||
- 连接池配置
|
||
|
||
#### 高级功能(阶段 10)
|
||
- 分页实现
|
||
- 搜索和过滤
|
||
- 排序和聚合
|
||
- 缓存策略
|
||
|
||
#### 生产准备(阶段 11-12)
|
||
- 配置管理(环境变量)
|
||
- 结构化日志记录
|
||
- 监控和指标收集
|
||
- Docker 容器化
|
||
- 部署策略
|
||
|
||
## 学习资源推荐
|
||
|
||
### 官方文档
|
||
- [Rust Book](https://doc.rust-lang.org/book/)
|
||
- [Axum Documentation](https://docs.rs/axum/)
|
||
- [Tokio Tutorial](https://tokio.rs/tokio/tutorial)
|
||
|
||
### 实用工具
|
||
- [Postman](https://www.postman.com/) - API 测试
|
||
- [SQLite Browser](https://sqlitebrowser.org/) - 数据库管理
|
||
- [Docker](https://www.docker.com/) - 容器化
|
||
|
||
### 社区资源
|
||
- [Rust Users Forum](https://users.rust-lang.org/)
|
||
- [r/rust](https://www.reddit.com/r/rust/)
|
||
- [Rust Discord](https://discord.gg/rust-lang)
|
||
|
||
## 常见问题解答
|
||
|
||
### Q: 为什么选择 Axum 而不是其他框架?
|
||
A: Axum 是由 Tokio 团队开发的现代 web 框架,具有以下优势:
|
||
- 类型安全的提取器系统
|
||
- 优秀的性能表现
|
||
- 与 Tokio 生态系统深度集成
|
||
- 活跃的社区支持
|
||
|
||
### Q: 内存存储什么时候应该迁移到数据库?
|
||
A: 当您需要以下功能时:
|
||
- 数据持久化
|
||
- 复杂查询
|
||
- 事务支持
|
||
- 多实例部署
|
||
|
||
### Q: 如何处理大量并发请求?
|
||
A: 考虑以下策略:
|
||
- 使用连接池
|
||
- 实现请求限流
|
||
- 添加缓存层
|
||
- 优化数据库查询
|
||
- 使用负载均衡
|
||
|
||
### Q: 生产环境部署需要注意什么?
|
||
A: 关键考虑因素:
|
||
- 环境配置管理
|
||
- 日志记录和监控
|
||
- 安全性(HTTPS、防火墙)
|
||
- 备份和恢复策略
|
||
- 性能监控
|
||
|
||
通过这个详细的学习指南,您将能够系统性地掌握 Rust web 开发的各个方面,从基础概念到生产级应用开发。 |