You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6.0 KiB
6.0 KiB
Storyboard API 响应格式统一与查询参数规范化
日期: 2026-02-11
类型: 重构
影响范围: /api/v1/storyboards 所有接口
变更概述
- 统一分镜 API 的响应格式,使其与项目级资源 API(
project_elements)保持一致 - 规范化查询参数命名,支持 camelCase 格式(前端友好)
问题描述
1. 不一致的响应格式
-
响应类型不一致
project_elements.py使用:SuccessResponse[T](来自app.schemas.common)storyboards.py使用:ApiResponse[T](来自app.schemas.response)
-
返回方式不一致
project_elements.py:直接返回SuccessResponse对象storyboards.py:使用success_response()函数返回字典
-
序列化方式不一致
project_elements.py:依赖 Pydantic 自动序列化storyboards.py:手动调用model_dump(by_alias=True, mode='json')
2. 查询参数命名不规范
查询参数使用 snake_case,前端需要额外转换:
project_id应支持projectIdpage_size应支持pageSizeinclude_items应支持includeItemsshot_size应支持shotSizecamera_movement应支持cameraMovement
解决方案
1. 统一响应格式
采用 project_elements.py 的模式:
- 使用
SuccessResponse[T]作为响应模型 - 直接返回
SuccessResponse对象 - 依赖 Pydantic 自动序列化
2. 规范化查询参数
为所有 snake_case 查询参数添加 camelCase alias:
# 修改前
project_id: str = Query(..., description="项目ID")
# 修改后
project_id: str = Query(..., alias="projectId", description="项目ID")
修改内容
1. 导入语句调整
# 修改前
from app.schemas.response import ApiResponse, success_response
# 修改后
from app.schemas.common import SuccessResponse
2. 响应模型调整
所有接口的 response_model 从 ApiResponse[T] 改为 SuccessResponse[T]
3. 返回语句调整
# 修改前
return success_response(
data=response_data.model_dump(by_alias=True, mode='json'),
message="分镜列表获取成功"
)
# 修改后
return SuccessResponse(
data=response_data,
message="分镜列表获取成功"
)
4. 查询参数 alias 添加
| 参数名 | alias | 接口 |
|---|---|---|
project_id |
projectId |
所有列表/筛选/搜索接口 |
page_size |
pageSize |
所有分页接口 |
include_items |
includeItems |
列表和详情接口 |
shot_size |
shotSize |
筛选接口 |
camera_movement |
cameraMovement |
筛选接口 |
涉及的接口(共 14 个)
分镜 CRUD
GET /storyboards- 获取分镜列表 ✅ 响应格式 + 查询参数POST /storyboards- 创建分镜 ✅ 响应格式GET /storyboards/{storyboard_id}- 获取分镜详情 ✅ 响应格式 + 查询参数PUT /storyboards/{storyboard_id}- 更新分镜 ✅ 响应格式DELETE /storyboards/{storyboard_id}- 删除分镜 ✅ 响应格式
排序管理
POST /storyboards/reorder- 重新排序分镜 ✅ 响应格式
筛选和搜索
GET /storyboards/filter- 按景别和运镜筛选 ✅ 响应格式 + 查询参数GET /storyboards/search- 全文搜索分镜 ✅ 响应格式 + 查询参数GET /storyboards/statistics/duration- 获取时长统计 ✅ 响应格式 + 查询参数
元素关联管理
POST /storyboards/{storyboard_id}/items- 添加元素到分镜 ✅ 响应格式GET /storyboards/{storyboard_id}/items- 获取分镜的所有关联元素 ✅ 响应格式POST /storyboards/{storyboard_id}/items/reorder- 批量调整元素顺序 ✅ 响应格式PATCH /storyboards/items/{item_id}- 更新元素的关联属性 ✅ 响应格式DELETE /storyboards/items/{item_id}- 从分镜移除元素 ✅ 响应格式
技术细节
响应格式保持不变
虽然内部实现改变,但最终的 JSON 响应格式完全一致:
{
"success": true,
"code": 200,
"message": "分镜列表获取成功",
"data": {
"items": [...],
"total": 100,
"page": 1,
"pageSize": 50,
"totalPages": 2
},
"timestamp": "2026-02-11T10:30:00Z"
}
查询参数兼容性
添加 alias 后,两种格式都支持:
# snake_case(兼容旧版)
GET /api/v1/storyboards?project_id=xxx&page_size=50&include_items=true
# camelCase(推荐,前端友好)
GET /api/v1/storyboards?projectId=xxx&pageSize=50&includeItems=true
Pydantic 自动序列化优势
-
自动处理 camelCase 转换
- Schema 中配置的
alias_generator=to_camel自动生效 - 无需手动调用
model_dump(by_alias=True)
- Schema 中配置的
-
类型安全
- 编译时类型检查
- IDE 自动补全支持
-
代码简洁
- 减少重复的序列化代码
- 统一的返回模式
影响评估
前端影响
- 无影响:响应格式完全一致
- 改进:查询参数支持 camelCase,更符合前端命名习惯
后端影响
- 代码简化:移除了大量重复的
model_dump()调用 - 一致性提升:与其他 API 模块保持统一风格
- 维护性提升:统一的模式更易于维护和扩展
测试建议
-
回归测试
- 测试所有 14 个接口的响应格式
- 验证 camelCase 字段名正确转换
- 验证嵌套对象(如
items、metadata)的序列化
-
查询参数测试
- 测试 snake_case 参数(向后兼容)
- 测试 camelCase 参数(新格式)
- 测试混合使用两种格式
-
集成测试
- 前端调用接口验证兼容性
- 验证分页、筛选、搜索功能正常
相关文件
server/app/api/v1/storyboards.py- 主要修改文件server/app/schemas/common.py- SuccessResponse 定义server/app/schemas/storyboard.py- 分镜 Schema 定义
参考
- 参考实现:
server/app/api/v1/project_elements.py - 查询参数规范:
server/app/api/v1/projects.py、server/app/api/v1/folders.py - API 规范:项目统一使用
SuccessResponse作为成功响应格式