Flask 工具封装 (Utils): 统一 API 响应
Flask 工具封装 (Utils): 统一 API 响应
本文档深入解析 OakAMC 项目中 app/utils 下关于 API 统一响应的处理逻辑。在前后端分离的项目中,这是极其重要的一环。
1. 为什么需要统一响应格式?
如果不进行封装,可能会出现每个人写代码风格不一致的情况:
- 开发者 A:
return jsonify({'code': 200, 'msg': 'ok'}) - 开发者 B:
return jsonify({'status': 'success', 'message': 'done'}) - 开发者 C:
return jsonify({'result': 0, 'error': None})
后果: 前端工程师需要为每个接口写适配器,导致维护噩梦。
因此,我们在 app/utils/api_response.py 中强制规定了唯一的返回结构。
2. 核心代码解析 (ApiResponse)
文件位置: app/utils/api_response.py
2.1 依赖关系 (ErrorCode)
为了避免魔术数字(Magic Numbers,如 400, 404),我们首先在 app/utils/error_code.py 中定义了枚举类:
class ErrorCode(object): SUCCESS = 200 # 成功 BAD_REQUEST = 400 # 参数错误 NOT_LOGIN = 401 # 未登录 INFERROR = 1000 # 内部自定义逻辑错误2.2 响应类封装逻辑
ApiResponse 类本身虽然很简单,但它的设计意图很明确:全静态方法 (All Static Method) 工具类。
class ApiResponse(object):
# 基础方法:统一底层调用 jsonify @staticmethod def json(body={}): return jsonify(body)
# 成功场景封装 @staticmethod def success_data(data={}, msg='', show=True): # 强制统一结构:code, error, message, data, show return ApiResponse.json({ 'code': ErrorCode.SUCCESS, # 固定为 200 'error': False, # 显式告知无误 'message': msg, 'data': data, # 数据载荷 'show': show # 控制前端是否弹窗提示 })
# 错误场景封装 @staticmethod def error(msg='', show=True): return ApiResponse.json({ 'code': ErrorCode.BAD_REQUEST, # 固定为 400 'error': True, 'message': msg, 'show': show })2.3 关键设计点
- 静态方法: 不需要实例化
ApiResponse(),直接ApiResponse.success_data()调用,方便快捷。 - 强制结构: 无论成功还是失败,返回的JSON key 都是固定的(
code,error,message),前端拦截器可以统一处理。 show字段: 这是一个典型的前后交互约定。后端告诉前端:“这个消息要不要弹窗给用户看?”show=True: 前端把message弹个 Toast 出来。show=False: 前端只记录日志,不打扰用户。
3. 实际使用案例
在路由函数 (routes.py) 中,我们不再直接使用 jsonify。
场景一:查询成功
@bp.route('/users')def get_users(): users = UserService.get_all() # 优雅!直接返回数据 return ApiResponse.success_data(data=users, msg="查询成功")场景二:参数错误
@bp.route('/login', methods=['POST'])def login(): if not request.json.get('username'): # 优雅!直接报错 return ApiResponse.bad_request(msg="用户名不能为空")通过这种封装,整个项目的代码风格高度统一,任何新加入的开发者都能立即上手,且不容易犯错。