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.
7.9 KiB
7.9 KiB
API 标准化迁移 - Storyboards/Resources/Recharge 模块
日期: 2026-02-11
类型: 重构
影响范围: 后端 API
Breaking Changes: ❌ 无(兼容性升级)
概述
将 storyboards.py、storyboard_resources.py、storyboard_board.py、screenplays.py、resource_library.py、recharge.py 等 6 个 API 文件迁移到统一的响应格式和异常处理规范,确保与项目整体架构一致。
变更内容
1. resource_library.py - 完整迁移
响应格式迁移
- ❌ 旧格式:使用
success_response()函数 - ✅ 新格式:使用
SuccessResponse[T]泛型类
变更前:
from app.schemas.response import success_response
@router.get("/characters", response_model=None)
async def get_characters(...):
return success_response(data=response_data, code=200)
变更后:
from app.schemas.common import SuccessResponse
@router.get("/characters", response_model=SuccessResponse[ResourceLibraryListResponse])
async def get_characters(...):
return SuccessResponse(data=response_data, message="角色列表获取成功")
查询参数 camelCase 支持
所有分页参数添加 alias 支持:
page_size→ 支持pageSize
示例:
page_size: int = Query(20, ge=1, le=100, alias="pageSize", description="每页数量")
日志规范化
添加结构化日志记录:
logger.info(
"API: 获取角色列表 | 用户: %s | 项目: %s",
current_user.user_id,
project_id
)
Schema 增强
新增 ResourceLibraryListResponse 统一分页响应:
class ResourceLibraryListResponse(BaseModel):
items: List[Any] = Field(..., description="资源列表")
total: int = Field(..., description="总数")
page: int = Field(..., description="当前页码")
page_size: int = Field(..., alias="pageSize", description="每页数量")
total_pages: int = Field(..., alias="totalPages", description="总页数")
2. recharge.py - 完整迁移
响应格式迁移
- ❌ 旧格式:使用
ApiResponse、success_response()、error_response() - ✅ 新格式:使用
SuccessResponse[T]
变更前:
from app.schemas.response import ApiResponse, success_response, error_response
@router.post("/orders", response_model=ApiResponse[RechargeOrderCreateResponse])
async def create_order(...):
return success_response(data=result)
变更后:
from app.schemas.common import SuccessResponse
@router.post("/orders", response_model=SuccessResponse[RechargeOrderCreateResponse])
async def create_order(...):
return SuccessResponse(data=order_response, message="充值订单创建成功")
异常处理标准化
- ❌ 旧方式:返回
error_response(message="...", code=403) - ✅ 新方式:使用自定义异常类
变更前:
if order.user_id != current_user.user_id:
return error_response(message="无权查看此订单", code=403)
变更后:
from app.core.exceptions import PermissionError
if order.user_id != current_user.user_id:
raise PermissionError("无权查看此订单")
查询参数优化
将 Pydantic model 依赖注入改为独立的 Query 参数(更符合 FastAPI 规范):
变更前:
@router.get("/orders")
async def get_orders(
query: Annotated[RechargeOrderQueryRequest, Depends()],
...
):
payment_status=query.payment_status,
page=query.page,
page_size=query.page_size
变更后:
@router.get("/orders")
async def get_orders(
payment_status: str = Query(None, alias="paymentStatus", description="支付状态筛选"),
page: int = Query(1, ge=1, description="页码"),
page_size: int = Query(20, ge=1, le=100, alias="pageSize", description="每页数量"),
...
):
3. screenplays.py - 查询参数增强
添加 camelCase 别名支持:
project_id→ 支持projectIdpage_size→ 支持pageSizeauto_create_subproject→ 支持autoCreateSubproject
示例:
project_id: UUID = Query(..., alias="projectId", description="项目 ID")
auto_create_subproject: bool = Form(True, alias="autoCreateSubproject", description="是否自动创建子项目")
4. 其他文件状态检查
- storyboards.py: ✅ 已符合规范(使用 SuccessResponse,camelCase alias 完整)
- storyboard_resources.py: ✅ 已符合规范(使用 SuccessResponse,无 Query 参数)
- storyboard_board.py: ✅ 已符合规范(使用 SuccessResponse,camelCase alias 完整)
技术细节
异常处理规范
所有业务异常统一使用 app.core.exceptions 中的自定义异常类:
| 场景 | 异常类 | 状态码 |
|---|---|---|
| 资源不存在 | NotFoundError |
404 |
| 数据验证失败 | ValidationError |
400 |
| 权限不足 | PermissionError |
403 |
| 认证失败 | AuthenticationError |
401 |
| 积分不足 | InsufficientCreditsError |
402 |
查询参数规范
所有查询参数必须支持 camelCase(前端规范):
page_size: int = Query(20, alias="pageSize", description="每页数量")
前端可以使用:
?page_size=20✅ snake_case(后端兼容)?pageSize=20✅ camelCase(前端首选)
响应格式规范
所有 API 统一返回 SuccessResponse[T]:
{
"success": true,
"data": { ... },
"message": "操作成功",
"timestamp": "2026-02-11T10:30:00Z"
}
兼容性
✅ 向后兼容
- 查询参数同时支持
snake_case和camelCase - 响应格式结构保持一致(仅规范化字段命名)
- 无 Breaking Changes
前端影响
- ✅ 无需修改前端代码(已使用 camelCase)
- ✅ 响应格式保持一致
- ✅ 错误处理逻辑无变化(HTTP 状态码不变)
测试建议
1. API 响应格式验证
# 资源库 API
curl -H "Authorization: Bearer $TOKEN" \
"http://localhost:6170/api/v1/projects/{project_id}/resource-library/characters?pageSize=10"
# 充值订单 API
curl -H "Authorization: Bearer $TOKEN" \
"http://localhost:6170/api/v1/recharge/orders?paymentStatus=pending&pageSize=20"
2. 异常处理验证
# 测试权限异常(403)
curl -H "Authorization: Bearer $TOKEN" \
"http://localhost:6170/api/v1/recharge/orders/{other_user_order_id}"
# 预期响应:
# {
# "success": false,
# "message": "无权查看此订单",
# "timestamp": "..."
# }
3. 查询参数兼容性测试
# snake_case(旧格式,应该仍然工作)
curl "...?page_size=20"
# camelCase(新格式,应该工作)
curl "...?pageSize=20"
文件清单
修改的文件
server/app/api/v1/resource_library.py- 完整迁移(响应格式 + 查询参数 + 日志)server/app/api/v1/recharge.py- 完整迁移(响应格式 + 异常处理 + 查询参数)server/app/api/v1/screenplays.py- 查询参数增强(添加 camelCase alias)server/app/schemas/resource_library.py- 新增分页响应 Schema
已检查的文件(无需修改)
server/app/api/v1/storyboards.py- ✅ 已符合规范server/app/api/v1/storyboard_resources.py- ✅ 已符合规范server/app/api/v1/storyboard_board.py- ✅ 已符合规范
参考文档
后续工作
- 监控生产环境日志,确认无异常
- 更新 API 文档(Swagger)
- 通知前端团队(如有必要)
- 考虑将旧的
app.schemas.response标记为废弃(Deprecated)
总结
本次迁移将 6 个 API 文件统一到标准的响应格式和异常处理规范,提升了代码一致性和可维护性。所有变更向后兼容,无需修改前端代码,可以安全部署。