# RFC 135: 统一 API 响应格式 **状态**: 已实施 **创建日期**: 2026-01-26 **作者**: Kiro AI **类型**: 重构 ## 概述 实施统一的 API 响应格式,确保所有接口返回一致的数据结构,符合 `api-design.md` 规范要求。 ## 背景 ### 问题 当前所有 API 接口直接返回数据,未使用统一的响应包装格式: ```python # 当前实现 @router.get("/projects") async def get_projects(...): return {"items": [...], "total": 100} # 直接返回 ``` ### 规范要求 根据 `api-design.md`,所有接口应返回统一格式: ```json { "code": 200, "message": "Success", "data": { "items": [...], "total": 100 } } ``` ## 解决方案 ### 1. 创建统一响应模型 **文件**: `server/app/schemas/response.py` ```python from typing import Generic, TypeVar, Optional from pydantic import BaseModel T = TypeVar('T') class ApiResponse(BaseModel, Generic[T]): """统一 API 响应格式""" code: int = 200 message: str = "Success" data: Optional[T] = None def success_response(data=None, message="Success", code=200): """便捷函数:创建成功响应""" return {"code": code, "message": message, "data": data} def error_response(message, code=400, data=None, errors=None): """便捷函数:创建错误响应""" return {"code": code, "message": message, "data": data, "errors": errors} ``` ### 2. 修改所有路由 **修改前**: ```python @router.get("", response_model=ProjectListResponse) async def get_projects(...): result = await service.get_projects(...) return result ``` **修改后**: ```python from app.schemas.response import ApiResponse, success_response @router.get("", response_model=ApiResponse[ProjectListResponse]) async def get_projects(...): result = await service.get_projects(...) return success_response(data=result) ``` ## 实施范围 ### 修改的文件 **新增**: - `server/app/schemas/response.py` - 统一响应模型 **修改**: - `server/app/schemas/__init__.py` - 导出响应模型 - `server/app/api/v1/health.py` (2 个接口) - `server/app/api/v1/auth.py` (2 个接口) - `server/app/api/v1/users.py` (2 个接口) - `server/app/api/v1/folders.py` (15 个接口) - `server/app/api/v1/projects.py` (20 个接口) - `server/app/api/v1/ai.py` (10 个接口) **总计**: 51+ 个接口 ### 修改模式 1. **添加导入**: ```python from app.schemas.response import ApiResponse, success_response ``` 2. **更新 response_model**: ```python response_model=ApiResponse[OriginalSchema] ``` 3. **包装返回值**: ```python return success_response(data=result) ``` ## 响应格式示例 ### 成功响应 **单个对象**: ```json { "code": 200, "message": "Success", "data": { "id": "123", "name": "项目名称" } } ``` **列表响应**: ```json { "code": 200, "message": "Success", "data": { "items": [...], "total": 100, "page": 1, "pageSize": 20, "totalPages": 5 } } ``` **简单消息**: ```json { "code": 200, "message": "Success", "data": { "message": "操作成功" } } ``` ### 错误响应 ```json { "code": 400, "message": "验证失败", "data": null, "errors": [ { "field": "name", "message": "名称不能为空" } ] } ``` ## 影响分析 ### 前端影响 **修改前**: ```typescript const response = await api.getProjects() const projects = response.items // 直接访问 ``` **修改后**: ```typescript const response = await api.getProjects() const projects = response.data.items // 需要通过 data 访问 ``` ### 兼容性 - ❌ **不向后兼容**: 前端需要同步更新 - ✅ **类型安全**: TypeScript 会在编译时捕获错误 - ✅ **统一处理**: 前端可以统一处理响应格式 ## 优势 1. **一致性**: 所有接口返回格式统一 2. **可扩展**: 易于添加全局字段(如 `timestamp`、`traceId`) 3. **错误处理**: 成功和错误响应格式一致 4. **符合规范**: 与 `api-design.md` 保持一致 5. **类型安全**: 泛型支持确保类型正确 ## 后续工作 1. **前端适配**: 更新前端 API 调用代码 2. **错误处理**: 统一异常处理中间件 3. **文档更新**: 更新 API 文档示例 4. **测试**: 验证所有接口返回格式 ## 参考 - `api-design.md` - API 设计规范 - FastAPI 文档 - Response Model - Pydantic 文档 - Generic Models