flask-restful 是一款比較好用的 flask 外掛,它不僅自動為我們實現了資料的 json 化,還能對傳入引數進行驗證,優雅的替代了 form 表單。
程式碼結構:
app
|_api
| |_ __init__.py
| |_ parser.py
| |_ view.py
|
|_ __init__.py
|_ code.py
|_ util.py
app.py
具體程式碼如下:
parser.py
from flask_restful.reqparse import RequestParser
parser = RequestParser()
parser.add_argument("id", type=int, location="args", required=True)
# get 請求為args, post請求為json
在 view 中的使用
view.py
from flask_restful import Resource
from app.util import make_result
from .parser import parser
class Test(Resource):
def get(self):
req = parser.parse_args(strict=True)
id = req.get("id")
return make_result(data={"id": id})
還有 __init__.py 檔案設定路由
__init__.py
from .view import Test
from flask_restful import Api
from flask import Blueprint
api = Blueprint("api", __name__) # 設定藍圖
resource = Api(api)
resource.add_resource(Test, "/") # 設定路由
util.py 為一個設定檔案, 用來放我們自己定義的輸出規範。
util.py
from flask import jsonify
from app.code import Code
def make_result(data=None, code=Code.SUCCESS):
return jsonify({"code": code, "data": data, "msg": Code.msg[code]})
code.py 是我們自定義的錯誤碼
code.py
class Code:
SUCCESS = 1200
NO_PARAM = 1300
msg = {
SUCCESS: "success",
NO_PARAM: "no param"
}
app.py 為啟動檔案
app.py
from flask import Flask
from app.api import api
app = Flask(__name__)
app.register_blueprint(api)
if __name__ == "__main__":
app.run(debug=True)
當我們執行 python app.py 的時候,程式便啟動了起來。
我們在瀏覽器中輸入:localhost:5000/?id=123
即可看到:
{
"code": 1200,
"data":{
"id": 123
},
"msg": "success"
}
那當我們輸入: localhost:5000/?id=api
得到了:
{
"message":{
"id": "invalid literal for int() with base 10: `api`"
}
}
很明顯,我們期望得到一個 int 型的 id,這裡給了一個 str 型別的字串,於是得到了 status_code 為 40 0的 response。
我們肯定是希望以我們自己的定義訊息來輸出,即:
{
"code": 1300,
"data": null,
"msg": "no param"
}
flask-restful 並沒有提供相應的 api,經過檢視原始碼,發現 flask-restful abort 的程式碼是改寫的 flask 的 abort 程式碼,於是我們也改寫 flask-restful 的 abort 程式碼。
flask abort 原始碼:
def abort(status, *args, **kwargs):
return _aborter(status, *args, **kwargs)
非常簡單。
flask-restful 的 abort 原始碼:
def abort(http_status_code, **kwargs):
try:
original_flask_abort(http_status_code)
except HTTPException as e:
if len(kwargs):
e.data = kwargs
raise
也是非常的簡單,這裡的 original_flask_abort 即 flask 的 abort。
那現在改程式碼就很容易了,只要 http_status_code == 400,那麼就是我們的引數沒有接受正確,需要爆出格式化以後的錯誤。
在 app.py 中修改:
app.py
from flask import Flask, abort
import flask_restful
from app.api import api
from app.util import make_result
from app.code import Code
app = Flask(__name__)
app.register_blueprint(api)
def custom_abord(http_status_code, *args, **kwargs):
# 只要http_status_code 為400, 報引數錯誤
if http_status_code == 400:
abort(make_result(code=Code.NO_PARAM))
# 正常返回訊息
return abort(http_status_code)
# 把flask_restful中的abort方法改為我們自己定義的方法
flask_restful.abort = custom_abord
if __name__ == "__main__":
app.run(debug=True)
現在再次執行 python app.py
瀏覽器輸入:http://localhost:5000/?id=api
即可得到:
{
"code": 1300,
"data": null,
"msg": "no param"
}
輸入:http://localhost:5000/?id=111 檢測一下正常輸出:
{
"code": 1200,
"data":{
"id": 111
},
"msg": "success"
}
完美!