在flask-restplus下統一接口返回格式

背景

在使用flask+flask-restplus時,業務正常時接口函數返回一個可以json序列化的對象

@ns.route('/hello')
class Hello(Resource):
    def get(self):
        return ['hello', 'hi']

接口返回內容如下:

[
    "hello",
    "hi"
]

當業務異常(比如檢測到參數錯誤)時,一般調用abort函數,它會拋出一個HTTPException

@ns.route('/error')
class Error(Resource):
    def get(self):
        abort(400, 'params error')

接口返回內容如下:

{
    "message": "params error"
}

由於公司規範要求,需要使用統一的http請求響應模板,如下:

{
    'code': 100000,
    'message': 'xxx'
    'data': 'hello'
}

因此,我們需要對接口返回格式進行改造。

接口返回值統一處理

爲了不改變原有的編碼習慣,又能夠達到以上返回格式的要求,我們可以使用flask-restplus的representation裝飾器來註冊一個接口返回內容處理器

@api.representation('application/json')
def output_json(data, code, headers=None):
    result = {}
    if api.specs_url == request.url:
        result = data
    elif code in (200, 201, 204):
        result['code'] = 100000
        result['data'] = data
    else:
        result['code'] = data.get('code') or 200000
        result['message'] = data['message']
    response = make_response(json.dumps(result), code)
    response.headers.extend(headers or {})
    return response

現在再來請求上面的兩個接口,返回格式變成了我們想要的格式

{"code": 100000, "data": ["hello", "hi"]}
{"code": 200000, "message": "params error"}

非HTTPException的異常處理

如果拋出不是HTTPException的異常,會發現並不能得到具體的異常內容,只會得到以下結果:

{"code": 200000, "message": "Internal Server Error"}

如果想要將一些指定的異常內容返回,比如我們自定義了以下的異常類:

class BaseException(Exception):
    http_code = 500
    business_code = 200000

    def __init__(self, message=None):
        if message:
            self.message = message

    def to_dict(self):
        data = {'code': self.business_code, 'message': self.message}
        return data


class InsufficientPrivilege(BaseException):
    http_code = 403
    business_code = 200001
    message = '權限不足'

那麼我們可以使用flask-restplus的errorhandler裝飾器來註冊一個異常處理器,在這個處理器中將自定義異常轉換爲正常接口返回格式

@api.errorhandler(BaseException)
def handle_base_exception(error):
    return error.to_dict(), error.http_code

這樣自定義異常也可以返回異常內容了

{"code": 200001, "message": "權限不足"}

當然我們也不能將所有異常一股腦拋出,這樣做的話會將因程序不健壯導致的異常也拋出,會給用戶帶來不好的體驗。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章