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.
2.7 KiB
2.7 KiB
修复项目 API 响应序列化问题
日期: 2026-01-21
类型: Bug 修复
影响范围: 后端 API - 项目模块
问题描述
创建项目时前端收到的响应数据格式不正确,导致:
- 前端无法正确获取项目 ID
- 导航到项目详情页时使用了错误的 ID(undefined 或错误值)
- 后端尝试将非 UUID 字符串转换为 UUID 时抛出 500 错误
根本原因
Project 模型的 id 字段定义了 alias="project_id",但 ProjectResponse schema 期望字段名为 id。FastAPI 在序列化时使用了 alias,导致前端收到的字段名不一致。
# 模型定义
class Project(SQLModel, table=True):
id: UUID = Field(
sa_column=Column(...),
alias="project_id" # ❌ 这导致了序列化问题
)
解决方案
在所有返回 Project 对象的 API 端点中,手动构建响应字典,确保字段名使用 camelCase 格式:
@router.post("", response_model=ProjectResponse, summary="创建项目")
async def create_project(...):
service = ProjectService(session)
project = await service.create_project(...)
# 手动构建响应
return {
"id": str(project.id), # ✅ 使用正确的字段名
"name": project.name,
"type": project.type_str,
"ownerId": str(project.owner_id),
"folderId": str(project.folder_id) if project.folder_id else None,
# ... 其他字段
}
修改的端点
POST /api/v1/projects- 创建项目GET /api/v1/projects- 获取项目列表GET /api/v1/projects/{id}- 获取项目详情PUT /api/v1/projects/{id}- 更新项目POST /api/v1/projects/{id}/move- 移动项目PUT /api/v1/projects/{id}/order- 更新项目顺序
测试验证
- 创建项目返回正确的 UUID
- 项目列表返回正确的字段名
- 项目详情返回正确的字段名
- 更新项目返回正确的字段名
- 前端可以正确导航到项目详情页
后续优化建议
考虑以下方案避免手动构建响应:
- 移除 alias:修改
Project模型,移除alias="project_id" - 自定义序列化器:实现自定义的 Pydantic 序列化器
- 使用 model_dump:在 service 层返回字典而非模型实例
相关文件
server/app/api/v1/projects.py- 修改了 6 个端点server/app/models/project.py- 问题根源(未修改)server/app/schemas/project.py- Response schema 定义
影响
- ✅ 修复了创建项目后无法跳转的问题
- ✅ 修复了 500 错误(UUID 转换失败)
- ✅ 统一了前后端字段命名(camelCase)
- ⚠️ 增加了代码重复(每个端点都需要手动构建响应)