Files
mock-server/CLAUDE.md
CNWei ab368ead1b feat: 实现文件上传功能并完善测试覆盖
- 新增 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>
2026-03-19 22:11:42 +08:00

229 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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