tips:
某日,本人终于受不了前人挖坑,大怒!!!V1版本项目restful接口返回一团糟,没有固定的格式,前端大佬也是抱怨多次。在本人的积极怂恿下,项目经理决定重写项目,解决诸多历史遗留问题(多得我想哭,自找的)。
{ "code":0, "msg":"成功", "data":null}
编码 | 含义 |
---|---|
0 | 成功 |
20001 | 登录成功 |
… | … |
编码 | 含义 |
---|---|
-1 | 失败 |
40000 | 自定义错误("{model} not have {key} ") |
40001 | 账户或密码错误 |
40002 | 参数无效 |
40003 | 未找到相关资源 |
… | … |
编码 | 含义 |
---|---|
50001 | 服务器错误,请联系管理员 |
50002 | 计算出错 |
… | … |
编写响应码类和响应消息类(code.py)
class ResponseCode(object): SUCCESS = 0 # 成功 FAIL = -1 # 失败 NO_RESOURCE_FOUND = 40001 # 未找到资源 INVALID_PARAMETER = 40002 # 参数无效 ACCOUNT_OR_PASS_WORD_ERR = 40003 # 账户或密码错误 class ResponseMessage(object): SUCCESS = "成功" FAIL = "失败" NO_RESOURCE_FOUND = "未找到资源" INVALID_PARAMETER = "参数无效" ACCOUNT_OR_PASS_WORD_ERR = "账户或密码错误"
Flask 接口返回实例(app.py)
from flask import Flask,jsonifyfrom code import ResponseCode,ResponseMessageapp =Flask(__name__)@app.route("/",methods=["GET"])def test(): test_dict = dict(name="zhang",age=18) data=dict(code=ResponseCode.SUCCESS, msg=ResponseMessage.SUCCESS, data=test_dict) return jsonify(data)if __name__=="__main__": app.run()
运行app,访问 http://127.0.0.1:5000/ 返回如下:{"code":0,"data":{"age":18,"name":"zhang"},"msg":"成功"}
进一步封装响应文本(response.py),减少重复代码的编写量及保持代码清洁
class ResMsg(object): """ 封装响应文本 """ def __init__(self, data=None, code=ResponseCode.SUCCESS, msg=ResponseMessage.SUCCESS): self._data = data self._msg = msg self._code = code def update(self, code=None, data=None, msg=None): """ 更新默认响应文本 :param code:响应状态码 :param data: 响应数据 :param msg: 响应消息 :return: """ if code is not None: self._code = code if data is not None: self._data = data if msg is not None: self._msg = msg def add_field(self, name=None, value=None): """ 在响应文本中加入新的字段,方便使用 :param name: 变量名 :param value: 变量值 :return: """ if name is not None and value is not None: self.__dict__[name] = value @property def data(self): """ 输出响应文本内容 :return: """ body = self.__dict__ body["data"] = body.pop("_data") body["msg"] = body.pop("_msg") body["code"] = body.pop("_code") return body
app中使用响应文本封装
from flask import Flask, jsonifyfrom code import ResponseCode, ResponseMessagefrom response import ResMsgapp = Flask(__name__)@app.route("/", methods=["GET"])def test(): res = ResMsg() test_dict = dict(name="zhang", age=18) res.update(data=test_dict) return jsonify(res.data)if __name__ == "__main__": app.run()
运行app,访问 http://127.0.0.1:5000/ 返回如下:{"code":0,"data":{"age":18,"name":"zhang"},"msg":"成功"}
实现全球化配置
实现思路是编写两份不一样的响应消息,前端通过选择语言,后端返回对应语言的消息。因此采用yaml编写响应消息,并加载到Flask应用中,通过语言选择返回不同的语言消息。在我的另外一篇文章《Flask后端实践 连载一 加载yaml配置文件》中介绍了Flask加载配置yaml文件。
zh_CN: &zh 0: "成功" -1: "失败" 40001: "资源不存在" 40002: "参数无效" 40003: "账户或密码错误"en: <<: *zh # 英文编码 0: "success" -1: "fail" 40001: "No resources found" 40002: "Invalid argument" 40003: "Incorrect account or password"
from code import ResponseCodefrom flask import request, current_appclass ResMsg(object): """ 封装响应文本 """ def __init__(self, data=None, code=ResponseCode.SUCCESS, rq=request): # 获取请求中语言选择,如果不存在,获取配置中的语言,如果配置中语言不存在,则默认为中文 self.lang = rq.headers.get("lang", current_app.config.get("LANG", "zh_CN") ) self._data = data self._msg = current_app.config[self.lang].get(code, None) self._code = code def update(self, code=None, data=None, msg=None): """ 更新默认响应文本 :param code:响应编码 :param data: 响应数据 :param msg: 响应消息 :return: """ if code is not None: self._code = code # 获取配置中对应语言的响应消息,默认为None self._msg = current_app.config[self.lang].get(code, None) if data is not None: self._data = data if msg is not None: self._msg = msg def add_field(self, name=None, value=None): """ 在响应文本中加入新的字段,方便使用 :param name: 变量名 :param value: 变量值 :return: """ if name is not None and value is not None: self.__dict__[name] = value @property def data(self): """ 输出响应文本内容 :return: """ body = self.__dict__ body["data"] = body.pop("_data") body["msg"] = body.pop("_msg") body["code"] = body.pop("_code") return body
from flask import Flask, jsonifyimport yamlfrom code import ResponseCodefrom response import ResMsgapp = Flask(__name__)with open("msg.yaml", encoding="utf-8") as f: msg_conf = yaml.safe_load(f)app.config.update(msg_conf)@app.route("/", methods=["GET"])def test(): res = ResMsg() test_dict = dict(name="zhang", age=18) # 此处只需要填入响应状态码,即可获取到对应的响应消息 res.update(code=ResponseCode.SUCCESS, data=test_dict) return jsonify(res.data)if __name__ == "__main__": app.run()
运行app,访问 http://127.0.0.1:5000/ ,利用postman设置不同的请求头,返回如下:
中文(headers中lang=zh_CN):{ "code": 0,"data": {"age": 18,"name": "zhang"},"lang": "zh_CN","msg": "成功"}
英文(headers中lang=en):{ "code": 0,"data": {"age": 18,"name": "zhang"},"lang": "en","msg": "success"}
注意:
联系客服