第 09 章 统一响应与异常处理
学习目标
学完本章,你应该能:
- 理解为什么要统一响应格式
- 掌握 fba 的统一返回模型和返回方法
- 学会自定义响应状态码
一、为什么要统一响应格式
想象一个项目,A 接口返回 {"code": 200, "msg": "成功", "data": {...}},B 接口返回 {"status": "ok", "result": {...}},C 接口直接返回数据。前端同学就得写三套解析逻辑,苦不堪言。
统一响应格式就是让所有接口返回结构一致,前端只需写一套解析逻辑。
fba 的统一响应结构长这样:
{
"code": 200, // 状态码
"msg": "请求成功", // 提示信息
"data": null // 业务数据
}三个字段的含义:
| 字段 | 含义 |
|---|---|
code | 业务状态码,200 表示成功 |
msg | 提示信息,给用户或前端看 |
data | 真正的业务数据,可为任意类型 |
统一响应的意义
二、统一返回模型
fba 提供了统一的 Pydantic 模型 ResponseModel:
class ResponseModel(BaseModel):
code: int = 200
msg: str = '请求成功'
data: Any | None = None使用时有两种写法(任选其一):
# 方式一:response_model 参数
@router.get('/test', response_model=ResponseModel)
def test():
return ResponseModel(data={'test': 'test'})
# 方式二:-> 类型标注
@router.get('/test')
def test() -> ResponseModel:
return ResponseModel(data={'test': 'test'})三、Schema 模式(让文档显示 data 结构)
ResponseModel 有个小问题:Swagger 文档里看不出 data 里面是什么结构。于是 fba 提供了 ResponseSchemaModel:
class ResponseSchemaModel(ResponseModel, Generic[SchemaT]):
data: SchemaT用法:
@router.get('/test', response_model=ResponseSchemaModel[GetUserDetail])
def test():
return ResponseSchemaModel[GetUserDetail](data=GetUserDetail(...))这样 Swagger 文档就能显示 data 里的完整字段结构了。
建议:查询类接口用
ResponseSchemaModel(让文档更清晰),其他接口用ResponseModel即可。
两种返回模型的区别
四、统一返回方法(response_base)
fba 提供了全局响应实例 response_base,极大简化返回写法。它有三个方法:
| 方法 | 用途 | 默认返回 |
|---|---|---|
success() | 成功响应 | code=200, msg="请求成功" |
fail() | 失败响应 | code=400, msg="请求错误" |
fast_success() | 大 JSON 快速成功 | 同 success,但解析性能更高 |
用法示例:
@router.get('/test')
def test() -> ResponseModel:
return response_base.success(data={'test': 'test'})
@router.get('/test')
def test() -> ResponseModel:
return response_base.fail(msg='参数错误')注意:这三个都是同步方法(非 async)。因为它们不涉及 IO 操作,定义为异步反而增加协程开销。
五、自定义响应状态码
实际项目中,状态码往往需要按业务约定调整。fba 内置了 CustomResponseCode 和 CustomResponse 来定义自己的状态码:
# 定义自定义响应
res = CustomResponse(code=0, msg='成功')
# 用法一:直接构造
return ResponseModel(code=res.code, msg=res.msg, data={'test': 'test'})
# 用法二:传给 response_base
return response_base.success(res=res, data={'test': 'test'})六、驼峰返回
前面提过,fba 默认用 Python 下划线命名(user_name),但前端多用小驼峰(userName)。fba 通过 SchemaBase 自动转换,返回给前端的数据自动变成小驼峰,无需手动处理。
七、异常处理
fba 对异常有统一处理机制(在 common/response/ 目录下)。核心思路:
- 业务异常统一抛出,统一捕获,统一转成
{code, msg, data}格式返回 - 定义了标准的错误码体系,避免散落的
raise Exception('xxx')
异常处理流程
完整异常处理细节可参考官方文档和源码,核心记住一点:异常也要走统一格式。
八、常见疑问
Q1:success() 和 fast_success() 有什么区别?fast_success() 专为返回大型 JSON 设计,能大幅提升解析性能。普通接口用 success() 即可,大数据量场景用 fast_success()。
Q2:为什么返回方法不是异步的? 因为这些方法只是构造数据对象,不涉及 IO(不查数据库、不读文件),定义为同步即可,还能省去协程调度开销。
本章小结
关键要点回顾:
- 统一响应格式:
{code, msg, data} - 两个返回模型:
ResponseModel(通用)、ResponseSchemaModel(文档显示 data 结构) - 返回方法:
response_base.success() / fail() / fast_success() - 状态码可用
CustomResponse自定义 - 返回数据自动转小驼峰
下一步: 第 10 章讲数据库会话与事务,这是写"增删改"操作必须掌握的核心概念。
对应官方文档:
接口响应(backend/reference/response.html)