# API设计规范 > **版本:** v2.0 > **最后更新:** 2025-11-06 > **API风格:** RESTful API > **基础URL:** `http://localhost:3001/api/v1` > **适用范围:** 平台层 + 能力层 + 业务模块层 --- ## 📋 设计原则 ### API First原则 - ✅ 先设计API,再实现功能 - ✅ API是前后端的契约 - ✅ API变更需要版本控制 - ✅ 所有API都要有文档 ### RESTful设计 - ✅ 使用HTTP动词表示操作(GET、POST、PUT、DELETE) - ✅ URL表示资源,不表示动作 - ✅ 使用复数名词表示资源集合 - ✅ 嵌套资源不超过2层 - ✅ 使用HTTP状态码表示结果 ### 命名规范 - ✅ URL使用小写字母和连字符(kebab-case) - ✅ 查询参数使用驼峰命名(camelCase) - ✅ JSON字段使用驼峰命名(camelCase) --- ## 🎯 URL设计规范 ### 路径格式 ``` /api/v{version}/{module}/{resource}/{id?}/{action?} 示例: /api/v1/literature/projects # 获取文献项目列表 /api/v1/literature/projects/123 # 获取ID=123的项目 /api/v1/literature/projects/123/export # 导出项目(动作) ``` ### 模块前缀 | 模块 | 路由前缀 | 示例 | |------|---------|------| | 认证 | `/auth` | `/api/v1/auth/login` | | 用户 | `/users` | `/api/v1/users/me` | | AI问答 | `/chat` | `/api/v1/chat/conversations` | | 智能体 | `/agents` | `/api/v1/agents` | | AI文献 | `/literature` | `/api/v1/literature/projects` | | 知识库 | `/knowledge-bases` | `/api/v1/knowledge-bases` | | 数据清洗 | `/data-cleaning` | `/api/v1/data-cleaning/projects` | | 统计分析 | `/analysis` | `/api/v1/analysis/projects` | | 统计工具 | `/tools` | `/api/v1/tools` | | 稿件审查 | `/review` | `/api/v1/review/tasks` | | LLM网关 | `/llm` | `/api/v1/llm/chat` | | 管理端 | `/admin` | `/api/v1/admin/users` | ### 资源命名 **✅ 正确示例:** ``` GET /api/v1/literature/projects # 获取列表 GET /api/v1/literature/projects/:id # 获取详情 POST /api/v1/literature/projects # 创建 PUT /api/v1/literature/projects/:id # 更新 DELETE /api/v1/literature/projects/:id # 删除 GET /api/v1/literature/projects/:id/items # 获取项目下的文献 POST /api/v1/literature/projects/:id/items/import # 导入文献 POST /api/v1/literature/projects/:id/screening/execute # 执行筛选 ``` **❌ 错误示例:** ``` POST /api/v1/literature/getProjects # 使用动词 POST /api/v1/literature/createProject # 使用动词 GET /api/v1/literature/project # 单数形式 GET /api/v1/literatureProjectList # 驼峰命名 ``` --- ## 🔧 HTTP方法规范 ### 方法使用 | 方法 | 用途 | 是否幂等 | 是否安全 | |------|------|---------|---------| | **GET** | 获取资源 | ✅ | ✅ | | **POST** | 创建资源 | ❌ | ❌ | | **PUT** | 完整更新资源 | ✅ | ❌ | | **PATCH** | 部分更新资源 | ❌ | ❌ | | **DELETE** | 删除资源 | ✅ | ❌ | ### 方法示例 ```http # 获取资源列表 GET /api/v1/literature/projects # 获取单个资源 GET /api/v1/literature/projects/123 # 创建资源 POST /api/v1/literature/projects Content-Type: application/json { "name": "新项目", "description": "..." } # 完整更新资源(所有字段) PUT /api/v1/literature/projects/123 Content-Type: application/json { "name": "更新", "description": "..." } # 部分更新资源(部分字段) PATCH /api/v1/literature/projects/123 Content-Type: application/json { "name": "只更新名称" } # 删除资源 DELETE /api/v1/literature/projects/123 ``` --- ## 📊 状态码规范 ### 标准状态码 | 状态码 | 含义 | 使用场景 | |--------|------|---------| | **200** | OK | 成功返回数据 | | **201** | Created | 成功创建资源 | | **204** | No Content | 成功但无返回数据(如删除) | | **400** | Bad Request | 请求参数错误 | | **401** | Unauthorized | 未认证(没有Token或Token过期) | | **403** | Forbidden | 无权限(已认证但权限不足) | | **404** | Not Found | 资源不存在 | | **409** | Conflict | 资源冲突(如重复创建) | | **422** | Unprocessable Entity | 语义错误(如验证失败) | | **429** | Too Many Requests | 请求过于频繁(限流) | | **500** | Internal Server Error | 服务器错误 | ### 状态码使用示例 ```typescript // 200 OK - 成功获取数据 res.status(200).json({ success: true, data: projects }); // 201 Created - 成功创建资源 res.status(201).json({ success: true, data: newProject }); // 204 No Content - 成功删除(无内容返回) res.status(204).send(); // 400 Bad Request - 参数错误 res.status(400).json({ success: false, error: { code: 'INVALID_PARAMS', message: '参数错误' } }); // 401 Unauthorized - 未认证 res.status(401).json({ success: false, error: { code: 'UNAUTHORIZED', message: '请先登录' } }); // 403 Forbidden - 无权限 res.status(403).json({ success: false, error: { code: 'FORBIDDEN', message: '无权访问' } }); // 404 Not Found - 资源不存在 res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '资源不存在' } }); // 422 Unprocessable Entity - 验证失败 res.status(422).json({ success: false, error: { code: 'VALIDATION_ERROR', message: '参数验证失败', details: [...] } }); ``` --- ## 📝 响应格式规范 ### 统一响应格式 ⭐ 必须遵守 **成功响应:** ```json { "success": true, "data": { // 实际数据 }, "message": "操作成功" } ``` **错误响应:** ```json { "success": false, "error": { "code": "ERROR_CODE", "message": "错误信息", "details": [...] // 可选,详细错误信息 } } ``` ### 列表数据响应 ```json { "success": true, "data": { "items": [ { "id": 1, "name": "项目1" }, { "id": 2, "name": "项目2" } ], "pagination": { "page": 1, "pageSize": 10, "total": 100, "totalPages": 10, "hasNext": true, "hasPrev": false } }, "message": "获取成功" } ``` ### 验证错误响应 ```json { "success": false, "error": { "code": "VALIDATION_ERROR", "message": "参数验证失败", "details": [ { "field": "email", "message": "邮箱格式不正确" }, { "field": "password", "message": "密码长度必须大于6位" } ] } } ``` --- ## 🔑 认证与授权规范 ### JWT认证 **1. 登录获取Token** ```http POST /api/v1/auth/login Content-Type: application/json { "email": "user@example.com", "password": "password123" } # Response { "success": true, "data": { "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "expiresIn": 604800, // 7天(秒) "user": { "id": 123, "email": "user@example.com", "name": "张三", "role": "user" } } } ``` **2. 使用Token访问API** ```http GET /api/v1/literature/projects Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` **3. Token过期处理** ```http # Token过期,返回401 { "success": false, "error": { "code": "TOKEN_EXPIRED", "message": "Token已过期,请重新登录" } } # 使用refreshToken刷新 POST /api/v1/auth/refresh Content-Type: application/json { "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } ``` ### 权限控制 | 端点类型 | 需要认证 | 角色要求 | |---------|---------|---------| | 公开端点 | ❌ | 无 | | 用户端点 | ✅ | user | | 管理端点 | ✅ | admin | **示例:** ```typescript // 公开端点(无需认证) POST /api/v1/auth/login POST /api/v1/auth/register // 用户端点(需要认证,user角色) GET /api/v1/literature/projects POST /api/v1/literature/projects // 管理端点(需要认证,admin角色) GET /api/v1/admin/users POST /api/v1/admin/users/:id/disable ``` --- ## 📄 分页规范 ### 请求参数 ``` GET /api/v1/literature/projects?page=1&pageSize=20&sortBy=createdAt&sortOrder=desc Query参数: - page: 页码(默认1) - pageSize: 每页数量(默认10,最大100) - sortBy: 排序字段(默认createdAt) - sortOrder: 排序方向(asc/desc,默认desc) ``` ### 响应格式 ```json { "success": true, "data": { "items": [...], "pagination": { "page": 1, "pageSize": 20, "total": 100, "totalPages": 5, "hasNext": true, "hasPrev": false } } } ``` --- ## 🔍 筛选与搜索规范 ### 筛选参数 ``` GET /api/v1/literature/projects?status=active&keyword=骨质疏松 Query参数: - status: 状态筛选(active/inactive) - keyword: 关键词搜索(搜索name和description字段) - userId: 用户ID筛选(管理端) - startDate/endDate: 日期范围筛选 ``` ### 搜索响应 ```json { "success": true, "data": { "items": [...], "pagination": {...}, "filters": { "status": "active", "keyword": "骨质疏松" } } } ``` --- ## ⚠️ 错误码设计 ### 标准错误码 | 错误码 | HTTP状态 | 说明 | |--------|---------|------| | `VALIDATION_ERROR` | 422 | 参数验证失败 | | `UNAUTHORIZED` | 401 | 未认证 | | `TOKEN_EXPIRED` | 401 | Token过期 | | `FORBIDDEN` | 403 | 无权限 | | `NOT_FOUND` | 404 | 资源不存在 | | `ALREADY_EXISTS` | 409 | 资源已存在 | | `QUOTA_EXCEEDED` | 429 | 配额超限 | | `INTERNAL_ERROR` | 500 | 服务器错误 | ### 业务错误码 ```typescript // 模块特定错误码(前缀区分) ASL_IMPORT_FAILED // AI文献:导入失败 ASL_SCREENING_IN_PROGRESS // AI文献:筛选进行中 PKB_QUOTA_EXCEEDED // 知识库:配额超限 LLM_QUOTA_EXCEEDED // LLM:配额超限 ``` --- ## 🚀 性能优化规范 ### 1. 分页必须 ``` 所有列表接口必须支持分页: - 默认pageSize=10 - 最大pageSize=100 - 禁止一次性返回全部数据 ``` ### 2. 字段过滤 ``` GET /api/v1/users/me?fields=id,name,email 只返回需要的字段,减少数据传输 ``` ### 3. 缓存策略 ```http # 设置缓存头 Cache-Control: public, max-age=300 # 使用ETag ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4" If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4" # 返回304 Not Modified ``` --- ## ✅ 检查清单 **设计新API时必须检查:** - [ ] URL符合RESTful规范(使用名词+复数) - [ ] 使用正确的HTTP方法(GET/POST/PUT/DELETE) - [ ] 使用正确的HTTP状态码 - [ ] 响应格式符合统一规范(success + data/error) - [ ] 需要认证的接口检查JWT Token - [ ] 需要权限的接口检查用户角色 - [ ] 列表接口支持分页 - [ ] 列表接口支持排序 - [ ] 错误响应包含明确的错误码和错误信息 - [ ] 所有API都有文档说明 --- ## 🔗 相关文档 **总览:** - [API路由总览](./04-API路由总览.md) ⭐ 查看所有API端点 **模板:** - [API设计模板](../_templates/API设计-模板.md) **各模块设计:** - [平台基础层](../01-平台基础层/README.md) - [通用能力层](../02-通用能力层/README.md) - [业务模块层](../03-业务模块/README.md) --- **最后更新:** 2025-11-06 **维护人:** 技术架构师 **版本:** v2.0