Flask 擴展: 使用 Flask-RESTPlus 構建 Swagger API 文檔

上篇文章主要介紹了 flask-restplus 構建 rest api 的主要用法,這篇文章將介紹如何使用此擴展構建 文檔, 實現 文檔跟着代碼走.html

開啓文檔

上一篇文章已經提到, 文檔默認是開啓的,並且默認掛載到 / 根路由, 在使用 api = Api(app) 的時候, 會有個默認參數 doc='/', 這裏的 doc 是指定文檔地址掛載點的, 還有個參數爲 version, 它的值默認爲 1.0, 表示當前文檔的版本, 使用 title 參數能夠描述文檔標題. 示例代碼以下所示:python

from flask import Flask
from flask_restplus import Api, Resource

app = Flask(__name__)
api = Api(app, doc='/doc', version='1.0', title='學習 Flask-RESTPlus')

@api.route('/hello')
class HelloWorld(Resource):
    def get(self):
        return {'hello': 'world'}
複製代碼

此時 doc 參數設置爲 /doc, 那訪問 /doc 就能夠訪問到文檔:數據庫

文檔

如上所示,文檔的標題爲 學習 Flask-RESTPlus, 版本爲 1.0, 而且默認渲染資源路由. 有一點須要注意, 若是是使用 Flask 實例 初始化的 Api 對象, 那麼文檔的 base_url/, 可是若是是使用 藍圖 初始化, 而且在初始化藍圖對象時設置了 url_prefix 參數, 那麼文檔的 base_url 是掛載到藍圖的 url_prefix 上的. 如下代碼表示將文檔掛載到藍圖根路由, 即 /api/v1.json

api_v1 = Blueprint('api_v1', __name__, url_prefix='/api/v1')
api = Api(api_v1, version='1.0', title='API')
複製代碼

經過命名空間渲染文檔

上一小節中的文檔渲染出來爲默認的命名空間, 一個命名空間對應一個資源, 它的文檔也將列在其命名空間下, 如下爲示例:flask

from flask_restplus import Api, Namespace, Resource

app = Flask(__name__)
api = Api(app, doc='/', version='1.0', title='待辦列表API')

todos = Namespace('todos', description='待辦列表')
practice = Namespace('practice', description='練習')

api.add_namespace(todos)
api.add_namespace(practice)

@todos.route('')
class TODOList(Resource):
    def get(self):
        return []

@practice.route('')
class Practice(Resource):
    def get(self):
        return []
複製代碼

渲染出的文檔結果以下所示, 能夠看到渲染出的文檔一目瞭然:api

對象模型

使用 flask-restplus 提供的 fileds模型, 將它與 ORM 對象或者自定義類對應,能夠很方便渲染響應和請求參數. 其實它是相似於將對象進行序列化的工具, 在請求的時候, 經過模型判斷請求參數, 在響應的時候經過模型進行序列化. 同時文檔也能夠經過模型來渲染須要的請求參數以及響應數據結構.數據結構

基礎用法

model = api.model('Model', {
    'name': fields.String,
    'address': fields.String,
    'date_updated': fields.DateTime(dt_format='rfc822'),
})
複製代碼

以上建立了一個名爲 Model 擁有三個字段的模型, 建立完成後可使用 api.expect(model) 來渲染請求參數文檔, 使用 api.response(mode=model) 來渲染響應數據文檔, 這個咱們接下來說.app

渲染效果

flask-restplus 提供的 api.expect 用來渲染請求參數, todos.response 用來渲染響應數據,有多個響應, 就能夠屢次使用此裝飾器, 如下代碼渲染出的文檔效果以下:工具

@todos.route('')
class TODOList(Resource):
 @todos.expect(model)
 @todos.response(code=200, model=model, description='請求成功響應')
    def get(self):
        return []
複製代碼

如圖所示, model 模型已經被自動轉化爲 json 格式的數據. 同時渲染出的 Swagger 文檔還提供了發送請求功能, 也就是右上角的 Try it out. 若是想要響應模型列表, 能夠這樣寫 todos.response(code=200, model=[model], description='請求成功響應'), 若是我只須要模型中的部分字段只用於響應, 另外一部分字段只用於請求,這就須要使用到 字段屬性 了.學習

模型字段

模型提供了不少直接對應 Python 數據類型的字段, 如下爲部分經常使用字段:

  • fields.Integer 表示數字
  • fields.String 表示字符串
  • fields.Datetime 表示日期
  • fields.List 表示列表
    • fields.List(fields.String) 將列表項字段傳入其中便可
  • etc

除了這些常規字段,若是一個字段對應的值是另外一個模型, 相似與數據庫 一對一 或者 一對多 的關係, 可使用 fields.Nested 字段. 使用方式以下:

model = api.model('Model', {
    'name': fields.String,
    'address': fields.String,
    'date_updated': fields.DateTime(dt_format='rfc822'),
})

# 直接引用一個模型
another_model = api.model('AnotherModel', {
    'model': fields.Nested(model)
})

# 引用模型列表
another_model = api.model('AnotherModel', {
    'model': fields.List(fields.Nested(model))
})

# 或者
another_model = api.model('AnotherModel', {
    'model': fields.Nested(model, as_list=True)
})
複製代碼

還有一些其餘字段以及高階用法, 能夠參考文檔

字段屬性

相似於 fields.String 或者 fields.Integer 的字段都擁有本身的屬性, 若是使用過 SQLalchemy 的話, 它與模型類的字段屬性是同一個性質, 能夠對屬性賦值, 來更加細緻的描述當前屬性:

  • required 用來設置是否爲必傳參數, 默認爲 False
  • readonly 用來設置只讀, 表示只有在響應的時候纔會出現, 默認爲 None
  • example 用力設置示例, 默認爲 None
  • description 屬性用來描述當前字段信息, 默認爲 None

部分字段屬性同時也提供了參數校驗功能, 對於 fields.String:

  • enum 一個列表, 字段的值只能是其中的某一個
  • min_length 字段最小長度
  • max_length 字段最大長度
  • pattern 使用正則判斷

對於 fields.Integer fields.Float:

  • min 最小值
  • max 最大值
  • exclusiveMin: 若是爲 True, 則左開區間, 默認爲 False
  • exclusiveMax: 若是爲 True, 則右開區間, 默認爲 False
  • multiple: 值必須是這個數的倍數

開啓參數驗證

使用 @todos.expect(model, validate=True) 就能夠開啓參數驗證, 參數驗證出錯會拋出 400 異常.

使用 parser 進行參數驗證

如上所述, 模型是以 json 的方式進行解析的, 若是傳入模型進行參數判斷, 那也只能校驗 json 參數, 因此在 expect 方法中, 除了根據模型, 也能夠根據 parser 校驗參數. 校驗參數的介紹能夠看上一篇文章, 或者直接查看文檔, 使用了 parser 後, 就能夠對 表單, 查詢字符串, 請求頭, 數據類型 等進行校驗.

url 參數渲染

對於 @api.route('/<int:id>') 中的參數, 可使用 @api.param('id', description='id') 進行渲染. 此裝飾器通常用來裝飾 資源類, 上面使用模型的方式通常用來裝飾 資源類方法, 也能夠裝飾 資源類, 好比 404 響應, 表示當前類下的每一個方法均可能會返回 404.

總結

使用兩篇文章分別介紹了 構建API構建API文檔, 但只是介紹了經常使用的一些使用方式, 對於更詳細和高階的用法仍是須要閱讀文檔. 其實 對象模型 是用來進行序列化的, 我使用起來感受不太好用, 就只用來生成文檔, 對於簡單的參數也會用它進行校驗. 對於序列化, 我比較喜歡使用 marshmallow, 它的用法和 對象模型 十分類似, 感興趣能夠去看下文檔.

相關文章
相關標籤/搜索