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.
4.7 KiB
4.7 KiB
统一响应格式使用错误修复
日期:2026-01-29
类型:Bugfix
影响范围:API 路由层
问题描述
在 app/api/v1/auth.py 中错误使用 ApiResponse.success() 导致运行时错误:
# ❌ 错误用法
return ApiResponse.success(data=result)
# AttributeError: success
根本原因
- 误解 Pydantic 模型用法:
ApiResponse是 Pydantic BaseModel,不是工具类 - 未查阅响应格式规范:直接猜测 API 而非查看
response.py实现 - 文档不完整:
api-design.md缺少后端实现细节
修复方案
1. 修复 API 路由代码
# app/api/v1/auth.py
# ✅ 修复前:错误导入
from app.schemas.response import ApiResponse
# ✅ 修复后:正确导入
from app.schemas.response import ApiResponse, success_response
# ✅ 修复前:错误使用
return ApiResponse.success(data=result)
# ✅ 修复后:使用便捷函数
return success_response(data=result)
2. 补充技术栈文档
更新 .claude/skills/jointo-tech-stack/references/api-design.md:
新增内容:
- ✅ 完整的响应格式字段说明(包括
success和timestamp) - ✅ 后端实现规范章节
- ✅ 三种正确使用方式(便捷函数、字典、Pydantic 实例)
- ✅ 错误用法警告
- ✅ 导入规范
- ✅ 类型注解示例
正确用法总结
方式 1:使用便捷函数(推荐)
from app.schemas.response import success_response
@router.post("/login/phone")
async def login_with_phone(request: PhoneLoginRequest):
result = await service.login_with_phone(...)
return success_response(data=result, message="登录成功")
方式 2:直接返回字典
from datetime import datetime, timezone
@router.post("/login/phone")
async def login_with_phone(request: PhoneLoginRequest):
result = await service.login_with_phone(...)
return {
"success": True,
"code": 200,
"message": "Success",
"data": result,
"timestamp": datetime.now(timezone.utc).isoformat()
}
方式 3:实例化 Pydantic 模型
from app.schemas.response import ApiResponse
@router.post("/login/phone")
async def login_with_phone(request: PhoneLoginRequest):
result = await service.login_with_phone(...)
return ApiResponse(
success=True,
code=200,
message="Success",
data=result
)
错误用法警告
# ❌ 错误:ApiResponse 不是工具类
return ApiResponse.success(data=result)
# AttributeError: success
# ❌ 错误:ApiResponse 没有 create() 方法
return ApiResponse.create(data=result)
# AttributeError: create
# ❌ 错误:ApiResponse 没有 ok() 方法
return ApiResponse.ok(data=result)
# AttributeError: ok
测试验证
单元测试
docker exec jointo-server-app pytest tests/unit/test_user_service.py -v
# ✅ 15/15 passed
集成测试
docker exec jointo-server-app pytest tests/integration/test_user_api.py -v
# ✅ 11/11 passed
影响范围
修改文件
server/app/api/v1/auth.py:修复 3 处错误用法.claude/skills/jointo-tech-stack/references/api-design.md:补充实现规范
涉及端点
POST /api/v1/auth/login/phone:手机号登录POST /api/v1/auth/refresh:刷新 TokenPOST /api/v1/auth/logout:用户登出
预防措施
1. 代码审查清单
- 检查是否正确导入
success_response函数 - 避免使用
ApiResponse.xxx()类方法形式 - 确保响应包含
success和timestamp字段
2. 开发规范
推荐做法:
- 优先使用
success_response()和error_response()便捷函数 - 需要类型注解时使用
ApiResponse[T] - 查阅
app/schemas/response.py确认正确用法
避免做法:
- 不要猜测 API,先查看源码
- 不要使用
ApiResponse.xxx()形式 - 不要省略
success和timestamp字段
3. 文档完善
- ✅ 已补充
api-design.md后端实现规范 - ✅ 已添加错误用法警告
- ✅ 已提供完整示例代码
相关文档
总结
本次修复解决了 ApiResponse 误用问题,并完善了技术栈文档。通过补充详细的实现规范和错误用法警告,可以有效避免类似问题再次发生。
关键要点:
ApiResponse是 Pydantic 模型,不是工具类- 使用
success_response()函数而非ApiResponse.success() - 遇到不确定的 API 时,先查看源码实现
- 保持文档与代码实现同步