# ADR 001: API 响应格式标准化 **状态**: 提议中 (Proposed) **日期**: 2026-02-11 **决策者**: 后端团队 **影响范围**: 所有 API 接口 ## 背景 项目中目前存在两套并行的 API 响应格式系统,导致代码不一致和维护困难: ### 当前状态 #### 系统 A:`app.schemas.response` (旧系统) ```python from app.schemas.response import ApiResponse, success_response @router.get("", response_model=ApiResponse[DataType]) async def get_data(): data = await service.get_data() return success_response( data=data.model_dump(by_alias=True, mode='json'), message="成功" ) ``` **使用模块**: - `projects.py` - `folders.py` - `recharge.py` - `wechat.py` - `attachments.py` - `ai.py` - `auth.py` - `health.py` - `public/shared_folders.py` **特点**: - 使用 `ApiResponse[T]` 泛型类 - 通过 `success_response()` 函数返回字典 - 需要手动调用 `model_dump(by_alias=True, mode='json')` - 代码冗余度高 #### 系统 B:`app.schemas.common` (新系统) ```python from app.schemas.common import SuccessResponse @router.get("", response_model=SuccessResponse[DataType]) async def get_data(): data = await service.get_data() return SuccessResponse( data=data, message="成功" ) ``` **使用模块**: - `credits.py` - `storyboards.py` - `project_resources.py` - `project_elements.py` - `project_element_tags.py` **特点**: - 使用 `SuccessResponse[T]` 泛型类 - 直接返回 Pydantic 对象 - 依赖 Pydantic 自动序列化 - 代码简洁,类型安全 #### 混用情况 - `storyboard_resources.py` 同时导入了两个系统 ❌ ### 问题分析 1. **代码不一致**:同一项目中存在两种不同的响应格式实现 2. **维护成本高**:开发者需要记住两套不同的使用方式 3. **代码冗余**:系统 A 需要在每个接口手动序列化 4. **类型安全性差**:系统 A 返回字典,失去类型检查优势 5. **新人困惑**:不清楚应该使用哪个系统 ## 决策 **统一使用 `app.schemas.common.SuccessResponse` 作为标准响应格式。** ### 理由 1. **符合 FastAPI 最佳实践** - 充分利用 Pydantic 的自动序列化能力 - 保持类型安全,IDE 支持更好 2. **代码更简洁** - 无需手动调用 `model_dump()` - 减少重复代码 - 统一的返回模式 3. **更易维护** - 单一职责:Pydantic 负责序列化 - 修改序列化逻辑只需改 Schema 配置 - 降低出错概率 4. **向前兼容** - 最终 JSON 响应格式完全一致 - 前端无需任何修改 ## 实施方案 ### 阶段 1:标准化 `common.py`(立即执行) 1. **确认 `SuccessResponse` 为标准** ```python # app/schemas/common.py class SuccessResponse(BaseModel, Generic[T]): success: bool = Field(default=True) code: int = Field(default=200) message: str = Field(default="Success") data: Optional[T] = Field(default=None) timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) ``` 2. **在 `response.py` 添加废弃警告** ```python # app/schemas/response.py import warnings warnings.warn( "app.schemas.response is deprecated. " "Use app.schemas.common.SuccessResponse instead.", DeprecationWarning, stacklevel=2 ) ``` ### 阶段 2:迁移现有 API(分批执行) **优先级 1(高频接口)**: - `projects.py` - 项目管理核心接口 - `folders.py` - 文件夹管理 - `ai.py` - AI 服务接口 **优先级 2(中频接口)**: - `auth.py` - 认证接口 - `recharge.py` - 充值接口 - `wechat.py` - 微信集成 **优先级 3(低频接口)**: - `attachments.py` - 附件管理 - `health.py` - 健康检查 - `public/shared_folders.py` - 公开分享 **迁移步骤**(每个文件): 1. 修改导入语句 ```python # 修改前 from app.schemas.response import ApiResponse, success_response # 修改后 from app.schemas.common import SuccessResponse ``` 2. 修改 `response_model` ```python # 修改前 @router.get("", response_model=ApiResponse[DataType]) # 修改后 @router.get("", response_model=SuccessResponse[DataType]) ``` 3. 修改返回语句 ```python # 修改前 return success_response( data=response_data.model_dump(by_alias=True, mode='json'), message="成功" ) # 修改后 return SuccessResponse( data=response_data, message="成功" ) ``` 4. 运行测试验证 5. 创建 Changelog ### 阶段 3:清理废弃代码(最后执行) 1. **确认所有模块已迁移** ```bash # 检查是否还有使用 response.py 的代码 grep -r "from app.schemas.response import" server/app/api/ ``` 2. **删除 `response.py`** - 或保留但标记为 `@deprecated` - 添加明确的迁移指南 3. **更新文档** - API 开发规范 - 代码审查清单 - 新人入职文档 ## 迁移检查清单 ### 代码修改 - [ ] 修改导入语句 - [ ] 修改 `response_model` 类型 - [ ] 修改返回语句(移除 `model_dump()`) - [ ] 运行 `getDiagnostics` 检查语法错误 ### 测试验证 - [ ] 单元测试通过 - [ ] 集成测试通过 - [ ] 响应格式验证(JSON 结构一致) - [ ] 前端兼容性测试 ### 文档更新 - [ ] 创建 Changelog - [ ] 更新 API 文档 - [ ] 更新开发规范 ## 影响评估 ### 前端影响 - **无影响**:JSON 响应格式完全一致 - **无需修改**:前端代码保持不变 ### 后端影响 - **代码简化**:每个接口减少 1-2 行序列化代码 - **类型安全**:编译时类型检查更严格 - **维护性提升**:统一模式,降低认知负担 ### 性能影响 - **无影响**:Pydantic 序列化性能相同 - **可能提升**:减少手动序列化的开销 ## 风险与缓解 ### 风险 1:迁移过程中引入 Bug **缓解措施**: - 分批迁移,每批完成后充分测试 - 保持 `response.py` 可用,出问题可快速回滚 - 使用自动化测试验证响应格式 ### 风险 2:开发者不知道新标准 **缓解措施**: - 在 `response.py` 添加废弃警告 - 更新开发文档和代码审查清单 - 团队内部培训和宣讲 ### 风险 3:第三方依赖使用旧格式 **缓解措施**: - 检查所有依赖和插件 - 必要时保留 `response.py` 作为兼容层 ## 替代方案 ### 方案 A:保持现状(不推荐) - **优点**:无需修改代码 - **缺点**:问题持续存在,技术债累积 ### 方案 B:统一到 `response.py`(不推荐) - **优点**:保持旧代码不变 - **缺点**:需要手动序列化,代码冗余 ### 方案 C:创建新的统一模块(不推荐) - **优点**:全新开始,避免历史包袱 - **缺点**:引入第三套系统,问题更严重 ## 后续工作 1. **制定迁移时间表** - 第 1 周:迁移优先级 1 接口 - 第 2 周:迁移优先级 2 接口 - 第 3 周:迁移优先级 3 接口 - 第 4 周:清理废弃代码 2. **更新开发规范** - API 响应格式标准 - 代码审查要点 - 最佳实践文档 3. **团队培训** - 新标准介绍 - 迁移指南讲解 - Q&A 答疑 ## 参考资料 - FastAPI 官方文档:[Response Model](https://fastapi.tiangolo.com/tutorial/response-model/) - Pydantic 文档:[Model Serialization](https://docs.pydantic.dev/latest/concepts/serialization/) - 项目现有实现: - `server/app/schemas/common.py` - `server/app/schemas/response.py` - `server/app/api/v1/project_elements.py`(参考实现) ## 决策结果 **待定** - 需要团队评审和批准 ## 评审记录 | 日期 | 评审人 | 意见 | 状态 | |------|--------|------|------| | 2026-02-11 | - | 待评审 | Pending | ## 更新历史 - 2026-02-11: 初始版本,提出统一响应格式方案