- 新增 upload.rs 模块,支持 multipart/form-data 文件上传 - 文件按日期存储在 storage/YYYY-MM-DD/ 目录下 - 使用 UUID 生成唯一文件名,保留原始扩展名 - 添加 axum-extra, uuid, chrono 依赖 新增测试用例: - config_test.rs: 6 个测试 (配置结构验证) - router_test.rs: 11 个测试 (路由匹配逻辑) - handler_test.rs: 8 个测试 (请求处理) - upload_test.rs: 13 个测试 (文件上传功能) 其他改进: - 优化 handler.rs 代码注释 - 更新 .gitignore 忽略 storage/ 和 .claude/ - 添加 CLAUDE.md 项目指南文档 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
229 lines
5.6 KiB
Markdown
229 lines
5.6 KiB
Markdown
# Mock Server 项目指南
|
||
|
||
## 项目概述
|
||
|
||
基于 Rust + Axum 的配置驱动型 Mock 服务,支持 YAML 配置、请求匹配、延迟响应、大文件流式返回和文件上传等特性。
|
||
|
||
## 技术栈
|
||
|
||
- **语言**: Rust (Edition 2024)
|
||
- **Web 框架**: Axum 0.8.8 + axum-extra (multipart 支持)
|
||
- **异步运行时**: Tokio
|
||
- **序列化**: serde + serde_yaml + serde_json
|
||
- **工具库**: walkdir, uuid, chrono, tokio-util
|
||
|
||
## 项目结构
|
||
|
||
```
|
||
mock-server/
|
||
├── src/
|
||
│ ├── main.rs # 程序入口,路由配置,服务启动
|
||
│ ├── lib.rs # 库模块导出
|
||
│ ├── config.rs # 配置结构定义 (MockRule, MockResponse, MockSettings)
|
||
│ ├── loader.rs # YAML 配置加载器,递归扫描 mocks 目录
|
||
│ ├── router.rs # 路由匹配引擎,基于路径首段索引
|
||
│ ├── handler.rs # 请求处理器,统一处理所有 Mock 请求
|
||
│ └── upload.rs # 文件上传处理模块
|
||
├── tests/ # 集成测试
|
||
│ ├── config_test.rs # 配置模块测试
|
||
│ ├── handler_test.rs # 请求处理测试
|
||
│ ├── integration_test.rs # 集成测试
|
||
│ ├── loader_test.rs # 加载器测试
|
||
│ ├── router_test.rs # 路由匹配测试
|
||
│ └── upload_test.rs # 文件上传测试
|
||
├── mocks/ # YAML Mock 配置文件目录
|
||
├── storage/ # 上传文件存储目录 (按日期分类: YYYY-MM-DD)
|
||
└── Cargo.toml
|
||
```
|
||
|
||
## 核心模块说明
|
||
|
||
### config.rs - 配置结构
|
||
|
||
定义 Mock 规则的数据结构:
|
||
- `MockRule`: 完整的 Mock 规则(id, request, response, settings)
|
||
- `MockRequest`: 请求匹配条件(method, path, query_params, headers, body)
|
||
- `MockResponse`: 响应配置(status, headers, body)
|
||
- `MockSettings`: 额外设置(delay_ms 延迟)
|
||
- `MockSource`: 支持单接口和多接口 YAML 格式
|
||
|
||
**文件协议**: body 以 `file://` 开头时,从磁盘流式读取文件
|
||
|
||
### loader.rs - 配置加载器
|
||
|
||
- `MockLoader::load_all_from_dir()`: 递归扫描目录下的 .yaml/.yml 文件
|
||
- 按路径首段建立索引(如 `/api/users` -> key: `api`)
|
||
- 支持单接口和多接口两种 YAML 格式
|
||
|
||
### router.rs - 路由匹配引擎
|
||
|
||
- 基于路径首段的 HashMap 快速索引
|
||
- 线性深度匹配:method -> path -> query_params -> headers -> body
|
||
- 支持大小写不敏感的方法匹配
|
||
- 支持尾部斜杠忽略
|
||
|
||
### handler.rs - 请求处理器
|
||
|
||
- 统一处理所有 HTTP 方法和路径
|
||
- 支持延迟响应(settings.delay_ms)
|
||
- 支持文件流式响应(低内存占用)
|
||
- 匹配失败返回 404
|
||
|
||
### upload.rs - 文件上传
|
||
|
||
- 路由: `POST /api/upload`
|
||
- 支持 multipart/form-data 格式
|
||
- 文件存储: `storage/YYYY-MM-DD/uuid.extension`
|
||
- 返回 JSON 格式的文件信息
|
||
|
||
## 常用命令
|
||
|
||
```bash
|
||
# 构建项目
|
||
cargo build
|
||
|
||
# 运行项目
|
||
cargo run
|
||
|
||
# 运行所有测试
|
||
cargo test
|
||
|
||
# 运行特定测试
|
||
cargo test test_name
|
||
|
||
# 检查代码
|
||
cargo check
|
||
|
||
# 格式化代码
|
||
cargo fmt
|
||
|
||
# 代码检查
|
||
cargo clippy
|
||
```
|
||
|
||
## YAML 配置示例
|
||
|
||
### 单接口模式
|
||
|
||
```yaml
|
||
id: "user-login"
|
||
request:
|
||
method: "POST"
|
||
path: "/api/v1/login"
|
||
query_params:
|
||
redirect: "/dashboard"
|
||
headers:
|
||
Content-Type: "application/json"
|
||
body:
|
||
username: "test"
|
||
password: "123456"
|
||
response:
|
||
status: 200
|
||
headers:
|
||
Content-Type: "application/json"
|
||
body: '{"code": 0, "message": "success", "data": {"token": "xxx"}}'
|
||
settings:
|
||
delay_ms: 100
|
||
```
|
||
|
||
### 多接口模式
|
||
|
||
```yaml
|
||
- id: "get-users"
|
||
request:
|
||
method: "GET"
|
||
path: "/api/users"
|
||
response:
|
||
status: 200
|
||
body: '{"users": []}'
|
||
|
||
- id: "create-user"
|
||
request:
|
||
method: "POST"
|
||
path: "/api/users"
|
||
response:
|
||
status: 201
|
||
body: '{"id": 1}'
|
||
```
|
||
|
||
### 文件响应模式
|
||
|
||
```yaml
|
||
id: "download-file"
|
||
request:
|
||
method: "GET"
|
||
path: "/api/download"
|
||
response:
|
||
status: 200
|
||
headers:
|
||
Content-Type: "application/pdf"
|
||
body: "file://./data/document.pdf"
|
||
```
|
||
|
||
## 开发规范
|
||
|
||
### 代码风格
|
||
|
||
- 使用 Rust 标准命名约定:snake_case for functions/variables, PascalCase for types
|
||
- 公开函数添加文档注释 `///`
|
||
- 错误处理使用 `Result` 和 `Option`
|
||
- 异步函数使用 `async/await`
|
||
|
||
### 测试规范
|
||
|
||
- 每个模块对应一个测试文件
|
||
- 测试函数命名:`test_<模块>_<场景>`
|
||
- 使用 `tempfile` crate 处理临时文件
|
||
- 测试应该独立运行,不依赖执行顺序
|
||
|
||
### Git 提交规范
|
||
|
||
```
|
||
feat: 新功能
|
||
fix: 修复 bug
|
||
docs: 文档更新
|
||
test: 测试相关
|
||
refactor: 代码重构
|
||
chore: 构建/工具变更
|
||
```
|
||
|
||
## API 端点
|
||
|
||
| 端点 | 方法 | 说明 |
|
||
|------|------|------|
|
||
| `/api/upload` | POST | 文件上传 |
|
||
| `/*` | ANY | Mock 请求处理(由 YAML 配置定义) |
|
||
|
||
## 文件上传响应格式
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"files": [
|
||
{
|
||
"original_name": "document.pdf",
|
||
"stored_name": "550e8400-e29b-41d4-a716-446655440000.pdf",
|
||
"path": "storage/2026-03-19/550e8400-e29b-41d4-a716-446655440000.pdf",
|
||
"size": 1024,
|
||
"content_type": "application/pdf"
|
||
}
|
||
],
|
||
"message": "Files uploaded successfully"
|
||
}
|
||
```
|
||
|
||
## 扩展功能规划
|
||
|
||
- [ ] 热加载:配置文件变更自动重载
|
||
- [ ] 动态占位符:支持 `{{timestamp}}`, `{{uuid}}` 等
|
||
- [ ] 管理界面:Web UI 管理 Mock 规则
|
||
- [ ] 请求录制:自动生成 Mock 配置
|
||
- [ ] 条件匹配:基于请求体的复杂匹配规则
|
||
|
||
## 注意事项
|
||
|
||
1. **文件协议**: 使用 `file://` 时确保文件路径正确
|
||
2. **延迟响应**: 仅用于测试,生产环境请移除
|
||
3. **上传目录**: 确保 `storage/` 目录有写入权限
|
||
4. **内存限制**: 请求体限制为 10MB
|