From b579a835de8721b5cbe95e97161187528dc97f99 Mon Sep 17 00:00:00 2001 From: CNWei Date: Tue, 24 Mar 2026 18:44:06 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E9=87=8D=E6=9E=84=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 CLAUDE.md 移至 .claude/ 目录,精简为 AI 开发指南 - 扩充 README.md 为完整的用户文档 - 新增 rules/mock-spec.md: YAML 配置生成规范 - 新增 rules/commit-spec.md: Git 提交消息格式规范 - 从 .gitignore 移除 .claude/ 目录以便跟踪 Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md => .claude/CLAUDE.md | 57 +++------------------- .claude/rules/commit-spec.md | 89 ++++++++++++++++++++++++++++++++++ .claude/rules/mock-spec.md | 89 ++++++++++++++++++++++++++++++++++ .claude/settings.local.json | 8 +++ README.md | 78 ++++++++++++++++++++++++++--- 5 files changed, 266 insertions(+), 55 deletions(-) rename CLAUDE.md => .claude/CLAUDE.md (70%) create mode 100644 .claude/rules/commit-spec.md create mode 100644 .claude/rules/mock-spec.md create mode 100644 .claude/settings.local.json diff --git a/CLAUDE.md b/.claude/CLAUDE.md similarity index 70% rename from CLAUDE.md rename to .claude/CLAUDE.md index b349d46..a7de980 100644 --- a/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -1,16 +1,4 @@ -# CLAUDE.md - -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. - -## 项目概述 - -基于 Rust + Axum 的配置驱动型 Mock 服务。在 `mocks/` 目录下通过 YAML 文件定义 API 行为,无需修改代码即可添加/修改接口。 - -**核心特性:** -- YAML 驱动的请求匹配(method、path、query_params、headers、body) -- 热重载:`mocks/*.yaml` 变更自动生效,无需重启服务 -- 大文件流式响应:通过 `file://` 协议从磁盘流式读取 -- 文件上传端点:`POST /api/upload` +# Mock Server 开发指南 ## 构建与测试命令 @@ -38,60 +26,31 @@ cargo fmt # 格式化代码 ``` **数据流:** + 1. `MockLoader` 扫描 `mocks/` 目录,解析 YAML 为 `MockRule` 结构体 2. 规则按路径首段建立索引(如 `/api/users` → key: `api`)存储于 `MockRouter` 3. 请求匹配顺序:method → path → query_params → headers → body 4. `AppState` 使用 `RwLock` 包装 router,支持线程安全的热重载 -**核心类型 (config.rs):** +## 核心类型 (config.rs) + - `MockRule`: 完整规则(id, request, response, settings) - `RequestMatcher`: 请求匹配条件(method, path, query_params, headers, body) - `MockResponse`: 响应配置(status, headers, body) - `MockSource`: 枚举类型,支持单接口/多接口 YAML 格式 -**请求匹配 (router.rs):** +## 请求匹配 (router.rs) + - 路径首段 HashMap 查找,O(1) 获取候选规则 - 候选集内线性扫描进行精确匹配 - Body 匹配:支持 JSON 对象和字符串两种比较方式 -**响应处理 (handler.rs):** +## 响应处理 (handler.rs) + - 内联 body:直接返回 - `file://` 前缀:从磁盘流式读取文件(低内存占用) - `settings.delay_ms`:模拟网络延迟 -## YAML 配置示例 - -**单接口模式:** -```yaml -id: "login" -request: - method: "POST" - path: "/api/login" - body: { "username": "test" } -response: - status: 200 - body: '{"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 -response: - body: "file://./data/large-file.pdf" -``` - ## 文件结构 ``` diff --git a/.claude/rules/commit-spec.md b/.claude/rules/commit-spec.md new file mode 100644 index 0000000..4da2bf4 --- /dev/null +++ b/.claude/rules/commit-spec.md @@ -0,0 +1,89 @@ +--- +paths: + - "**/*" +--- + +## Git 提交消息规范 + +AI 在生成 commit 消息时必须遵循以下格式。 + +### 格式 + +``` +<类型>(<范围>): <描述> + +[可选的详细说明] + +[可选的脚注] +``` + +### 类型(Type) + +| 类型 | 说明 | +|------|------| +| feat | 新功能(feature) | +| fix | 修复 bug | +| docs | 文档更新 | +| style | 代码格式(不影响功能的变动) | +| refactor | 代码重构(既非新功能也非 bug 修复) | +| test | 添加或修改测试 | +| chore | 构建系统或辅助工具的变动 | +| perf | 性能优化 | + +### 范围(Scope) + +描述提交影响的功能模块或组件(可选)。 + +### 描述(Description) + +- 简明扼要描述变动内容 +- 首字母小写 +- 不超过 100 个字符 +- 使用祈使句(如 "add" 而非 "added") + +### 详细说明(Body) + +- 提供更多上下文和详细说明(可选) +- 每行不超过 72 个字符 +- 说明"做了什么"和"为什么" + +### 脚注(Footer) + +- 破坏性变动说明(如 `BREAKING CHANGE: ...`) +- 关闭的 Issue(如 `Closes #123`) + +### 示例 + +**新功能:** + +``` +feat(api): 添加用户登录端点 + +- 实现 JWT 认证逻辑 +- 添加登录表单前端组件 +- 更新用户服务处理登录请求 + +Closes #45 +``` + +**Bug 修复:** + +``` +fix(router): 修复路径匹配大小写问题 + +路径匹配在某些情况下区分大小写导致无法正确路由到处理器。 +``` + +**文档更新:** + +``` +docs: 更新 README 中的安装说明 +``` + +**重构:** + +``` +refactor(handler): 简化响应处理逻辑 + +将文件响应和内联响应的处理逻辑分离到独立函数中。 +``` diff --git a/.claude/rules/mock-spec.md b/.claude/rules/mock-spec.md new file mode 100644 index 0000000..34ad8e6 --- /dev/null +++ b/.claude/rules/mock-spec.md @@ -0,0 +1,89 @@ +--- +paths: + - "mocks/**/*.{yml,yaml}" +--- + +## YAML 配置规范 + +AI 在生成 Mock 规则时必须遵循以下格式。 + +### 字段说明 + +| 字段 | 类型 | 必填 | 说明 | +|------|------|:----:|------| +| id | string | 是 | 规则唯一标识 | +| request.method | string | 是 | HTTP 方法 (GET/POST/PUT/DELETE...) | +| request.path | string | 是 | 请求路径,精确匹配 | +| request.query_params | object | 否 | 查询参数匹配 | +| request.headers | object | 否 | 请求头匹配(大小写不敏感) | +| request.body | any | 否 | 请求体匹配,支持 JSON 对象或字符串 | +| response.status | number | 是 | HTTP 状态码 | +| response.headers | object | 否 | 响应头 | +| response.body | string | 是 | 响应体,支持 file:// 前缀 | +| settings.delay_ms | number | 否 | 延迟响应(毫秒) | + +### 匹配规则 + +1. **路径精确匹配**(非前缀匹配) +2. **请求头匹配大小写不敏感** +3. **Body 匹配**支持 JSON 对象或字符串比较 + +### 配置示例 + +**单接口模式:** + +```yaml +id: "login" +request: + method: "POST" + path: "/api/login" + body: { "username": "test" } +response: + status: 200 + body: '{"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: "search-users" +request: + method: "GET" + path: "/api/users" + query_params: { "role": "admin" } + headers: { "Authorization": "Bearer token" } +response: + status: 200 + headers: { "X-Total-Count": "100" } + body: '{"users": []}' +``` + +**文件响应:** + +```yaml +id: "download-pdf" +request: + method: "GET" + path: "/api/download" +response: + status: 200 + body: "file://./data/large-file.pdf" +``` + +> `file://` 支持两种路径: +> - 相对路径:`file://./data/file.pdf`(相对于项目根目录) +> - 绝对路径:`file:///C:/path/to/file.pdf` diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..ea1c057 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,8 @@ +{ + "permissions": { + "allow": [ + "Bash(find:*)", + "Bash(cargo search:*)" + ] + } +} diff --git a/README.md b/README.md index 0539494..bcd0227 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,77 @@ # mock-server -基于Rust/Axum的配置驱动型Mock服务,支持YAML配置、请求匹配、延迟响应、大文件流式返回等特性。 + +基于 Rust/Axum 的配置驱动型 Mock 服务,支持 YAML 配置、请求匹配、热重载、延迟响应、大文件流式返回等特性。 ## 特性 -- 配置驱动:YAML定义API行为,无需修改代码 -- 高性能:基于Rust异步运行时,哈希索引匹配请求 -- 低内存:大响应体支持磁盘文件流式读取,不占用常驻内存 -- 易扩展:模块化设计,支持动态占位符、热加载(规划中) + +- **配置驱动**:YAML 定义 API 行为,无需修改代码 +- **热重载**:`mocks/*.yaml` 变更自动生效,无需重启服务 +- **高性能**:基于 Rust 异步运行时,路径首段哈希索引 O(1) 匹配 +- **低内存**:大响应体支持 `file://` 协议从磁盘流式读取 +- **文件上传**:内置 `/api/upload` 端点,按日期分目录存储 ## 快速开始 -### 1. 安装依赖 \ No newline at end of file + +### 1. 安装依赖 + +确保已安装 Rust 工具链: + +```bash +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +``` + +### 2. 构建与运行 + +```bash +cargo build # 构建项目 +cargo run # 启动服务 http://127.0.0.1:8080 +cargo test # 运行所有测试 +cargo test # 运行匹配的测试(如 cargo test router) +cargo clippy # 代码检查 +cargo fmt # 格式化代码 +``` + +## 文件结构 + +``` +src/ +├── main.rs # 入口,热重载监听,Axum 路由配置 +├── config.rs # 数据结构定义(MockRule, RequestMatcher 等) +├── loader.rs # YAML 解析,目录扫描 +├── router.rs # 路径首段索引,匹配逻辑 +├── handler.rs # 统一请求处理器,文件流式响应 +└── upload.rs # Multipart 文件上传处理 + +tests/ # 集成测试(每个模块一个测试文件) +mocks/ # YAML Mock 配置文件 +storage/ # 上传文件存储(按 YYYY-MM-DD 分目录) +``` + +## Mock 配置 + +详细配置规范请参考 [.claude/rules/mock-spec.md](.claude/rules/mock-spec.md) + +## API + +### 文件上传 + +```http +POST /api/upload +Content-Type: multipart/form-data + +file: +``` + +**响应示例:** + +```json +{ + "filename": "example.txt", + "path": "storage/2024-01-15/example.txt", + "size": 1024 +} +``` + +## 许可证 + +MIT