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.
 

8.6 KiB

Changelog: 项目相关 API 响应格式迁移

日期: 2026-02-11
类型: 架构优化
影响范围: server/app/api/v1/projects.py, server/app/api/v1/project_resources.py, server/app/api/v1/project_elements.py, server/app/api/v1/project_element_tags.py

变更概述

将项目相关的 4 个 API 文件统一迁移到 SuccessResponse 标准响应格式,并为所有查询参数添加 camelCase alias,提升前端开发体验。

问题背景

在 API 响应格式标准化过程中(详见 ADR-001),发现项目相关文件存在响应格式问题:

projects.py

# ❌ 使用旧系统
from app.schemas.response import ApiResponse, success_response

project_resources.py, project_elements.py, project_element_tags.py

# ✅ 已使用标准格式
from app.schemas.common import SuccessResponse

此外,部分查询参数缺少 camelCase alias,不符合前端命名习惯。

变更内容

1. projects.py 迁移

更新导入

# 修改前
from app.schemas.response import ApiResponse, success_response

# 修改后
from app.schemas.common import SuccessResponse

迁移接口

共迁移 18 个接口

项目 CRUD(6 个接口)

  • GET /api/v1/projects - 获取项目列表
  • POST /api/v1/projects - 创建项目
  • GET /api/v1/projects/{project_id} - 获取项目详情
  • PUT /api/v1/projects/{project_id} - 更新项目
  • DELETE /api/v1/projects/{project_id} - 删除项目(移至回收站)
  • GET /api/v1/projects/trash - 查看回收站

项目操作(5 个接口)

  • POST /api/v1/projects/{project_id}/restore - 从回收站恢复
  • DELETE /api/v1/projects/{project_id}/permanent - 永久删除
  • POST /api/v1/projects/{project_id}/move - 移动项目
  • POST /api/v1/projects/{project_id}/clone - 克隆项目
  • POST /api/v1/projects/{project_id}/export - 导出项目
  • PUT /api/v1/projects/{project_id}/order - 更新项目顺序

项目分享(3 个接口)

  • POST /api/v1/projects/{project_id}/shares - 创建分享
  • GET /api/v1/projects/{project_id}/shares - 获取分享列表
  • DELETE /api/v1/projects/{project_id}/shares/{share_id} - 撤销分享

项目成员(3 个接口)

  • GET /api/v1/projects/{project_id}/members - 获取项目成员列表
  • POST /api/v1/projects/{project_id}/members - 添加项目成员
  • DELETE /api/v1/projects/{project_id}/members/{user_id} - 移除项目成员

子项目(1 个接口)

  • GET /api/v1/projects/{parent_project_id}/subprojects - 获取子项目列表

迁移模式

# 修改前
@router.get("", response_model=ApiResponse[ProjectListResponse])
async def get_projects():
    result = await service.get_projects()
    return success_response(data=result)

# 修改后
@router.get("", response_model=SuccessResponse[ProjectListResponse])
async def get_projects():
    result = await service.get_projects()
    return SuccessResponse(data=result)

2. project_resources.py 查询参数优化

添加 camelCase alias

# 修改前
element_tag_id: Optional[str] = Query(None, description="标签ID过滤")
page_size: int = Query(20, ge=1, le=100, description="每页数量")

# 修改后
element_tag_id: Optional[str] = Query(None, alias="elementTagId", description="标签ID过滤")
page_size: int = Query(20, ge=1, le=100, alias="pageSize", description="每页数量")

修改的接口

  • GET /api/v1/projects/{project_id}/resources - 添加 elementTagId alias
  • GET /api/v1/tags/{tag_id}/resources - 添加 pageSize alias

3. project_elements.py 和 project_element_tags.py

状态 已符合标准,无需修改

这两个文件已经完全使用 SuccessResponse,且没有查询参数需要添加 alias。

关键改进

  1. 统一响应格式

    • 所有项目相关接口使用 SuccessResponse
    • 移除了 ApiResponsesuccess_response() 的使用
  2. 前端友好

    • 查询参数支持 camelCase(elementTagId, pageSize
    • 同时保持向后兼容(snake_case 仍然有效)
  3. 代码简洁

    • 统一的返回模式
    • 减少认知负担
  4. 类型安全

    • 明确的响应模型类型
    • 充分利用 Pydantic 类型系统

影响评估

前端影响

  • 无影响:JSON 响应格式完全一致
  • 体验提升:查询参数支持 camelCase,更符合前端命名习惯
  • 无需修改:前端代码保持不变

后端影响

  • 代码统一:项目模块完全使用标准响应格式
  • 维护性提升:统一模式,降低认知负担
  • API 文档改进:OpenAPI 文档类型更明确

性能影响

  • 无影响:Pydantic 序列化性能相同

测试验证

验证步骤

  1. 语法检查

    # 使用 getDiagnostics 检查
    ✅ server/app/api/v1/projects.py: No diagnostics found
    ✅ server/app/api/v1/project_resources.py: No diagnostics found
    ✅ server/app/api/v1/project_elements.py: No diagnostics found
    ✅ server/app/api/v1/project_element_tags.py: No diagnostics found
    
  2. 响应格式验证

    • 所有接口返回格式保持一致
    • 包含 success, code, message, data, timestamp 字段
  3. 查询参数验证

    • 支持 camelCase:?elementTagId=xxx&pageSize=20
    • 支持 snake_case:?element_tag_id=xxx&page_size=20(向后兼容)

建议测试

# 1. 启动服务
docker-compose up -d

# 2. 测试项目列表接口(camelCase 参数)
curl -X GET "http://localhost:8000/api/v1/projects?folderId={id}&contentType=video&sortBy=updated_at&sortOrder=desc&pageSize=10" \
  -H "Authorization: Bearer {token}"

# 3. 测试项目创建接口
curl -X POST "http://localhost:8000/api/v1/projects" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"name": "测试项目", "type": "mine"}'

# 4. 测试项目素材列表(camelCase 参数)
curl -X GET "http://localhost:8000/api/v1/projects/{id}/resources?elementTagId={tag_id}&pageSize=20" \
  -H "Authorization: Bearer {token}"

# 5. 测试项目角色列表
curl -X GET "http://localhost:8000/api/v1/projects/{id}/characters" \
  -H "Authorization: Bearer {token}"

# 6. 测试项目标签列表
curl -X GET "http://localhost:8000/api/v1/projects/{id}/element-tags" \
  -H "Authorization: Bearer {token}"

相关文档

  • ADR: docs/architecture/adrs/001-api-response-format-standardization.md
  • 迁移指南: 详见 ADR-001 中的迁移步骤
  • 标准格式: server/app/schemas/common.py

后续工作

根据 ADR-001 的三阶段计划,后续需要迁移的模块:

优先级 1(高频接口)

  • projects.py - 项目管理核心接口(已完成)
  • folders.py - 文件夹管理
  • resource_library.py - 资源库

优先级 2(中频接口)

  • auth.py - 认证接口
  • recharge.py - 充值接口
  • wechat.py - 微信集成

优先级 3(低频接口)

  • attachments.py - 附件管理
  • health.py - 健康检查
  • public/shared_folders.py - 公开分享

统计数据

  • 迁移文件数: 4(projects, project_resources, project_elements, project_element_tags)
  • 迁移接口数: 18(projects.py)
  • 已符合标准接口数: 25(project_resources: 7, project_elements: 12, project_element_tags: 6)
  • 总接口数: 43
  • 查询参数优化: 2 个参数添加 camelCase alias
  • 代码质量: 无 diagnostics 错误

技术收益

  1. 项目模块完全统一:所有项目相关接口使用标准响应格式
  2. 前端开发体验提升:查询参数支持 camelCase,符合前端命名习惯
  3. 代码简洁性:统一的返回模式,减少冗余代码
  4. 类型安全性:充分利用 Pydantic 类型系统
  5. API 文档质量:OpenAPI 文档类型更明确
  6. 为后续迁移铺路:建立了标准迁移模式

注意事项

  1. 废弃警告response.py 已添加废弃警告
  2. 不要混用:新代码必须使用 SuccessResponse
  3. 参考实现:这 4 个文件可作为迁移参考
  4. 项目模块完成:所有项目相关 API 已统一格式

总结

成功将项目相关的 4 个 API 文件统一到标准响应格式:

  • projects.py:已完成迁移(18 个接口)
  • project_resources.py:已符合标准 + 查询参数优化(7 个接口)
  • project_elements.py:已符合标准(12 个接口)
  • project_element_tags.py:已符合标准(6 个接口)

项目模块共 43 个接口全部使用 SuccessResponse 标准格式,查询参数支持 camelCase,解决了架构混用问题,为后续全面迁移建立了标准模式,同时保持了前端兼容性和代码质量。