Flask-RESTPlus
对于 REST Api 来说,Flask-RESTPlus 是一个优秀的 Api 文档生成工具,这个包将会替换 Flask 路由层的编写方式,通过自己的语法来规定 Api 细节,并生成 Api 文档。
安装
安装 Flask-RESTPlus:
pip install flask-restplus
或者:
easy_install flask-restplus
实践
这里会实现一个完整的小项目来实践和介绍 Flask-RESTPlus 这个库。我们实现一个简单的 图书订单系统 ,实现用户、图书和订单的 CURD。
Model
用户 model,包含 id 和 username:
class User(object):
user_id = None
username = None
def __init__(self, username: str):
self.user_id = str(uuid.uuid4())
self.username = username
图书 model,包含 id,名称和价格:
class Book(object):
book_id = None
book_name = None
price = None
def __init__(self, book_name: str, book_price: float):
self.book_id = str(uuid.uuid4())
self.book_name = book_name
self.price = book_price
订单 model,包含 id,购买者 id,图书 id 和创建时间:
class Order(object):
order_id = None
user_id = None
book_id = None
created_at = None
def __init__(self, user_id, book_id):
self.order_id = str(uuid.uuid4())
self.user_id = user_id
self.book_id = book_id
self.created_at = int(time.time())
蓝图
在 Flask 中构建大型 Web 项目,可以通过蓝图为路由分组,并在蓝图中添加通用的规则(url 前缀、静态文件路径、模板路径等)。这个项目我们只用一个 api 蓝图,在实际中可能会使用 openapi 蓝图,internal api 蓝图来区分大的分类。
而 Flask-RESTPlus 的 class::Api 将直接挂在在蓝图下面,这么我们即利用了 Flask 的蓝图进行对功能模块分类,也可以利用 Api 的版本对 Api 版本进行管理,对于小的模块分类,我们可以利用 Api 的 namespace,这里我们可以分为 user namespace,book namespace 和 order namespace:
1. Api 蓝图:
from flask import Blueprint
from flask_restplus import Api
api_blueprint = Blueprint("open_api", __name__, url_prefix="/api")
api = Api(api_blueprint, version="1.0",
prefix="/v1", title="OpenApi", description="The Open Api Service")
2.然后,就可以创建出不同的 namespace,来编写自己的 api 代码了。而只需要在 app 工厂中注册该 blueprint,便可将自己的编写的 api 挂载到 flask app 中。
def create_app():
app = Flask("Flask-Web-Demo")
# register api namespace
register_api()
# register blueprint
from apis import api_blueprint
app.register_blueprint(api_blueprint)
return app
```
##### 要注意的是,因为 Api 中很多工具方法依赖 api 对象,因此在注册 namespace 的时候要避免循环引用,而且,这注册蓝图的时候,需要先将 namespace 注册,否则会 404。这个库的很多方法太依赖 api 对象,感觉设计并不合理,很容易就循环引用,并不是非常优雅。
### 注册 namespace:
```python
def register_api():
from apis.user_api import ns as user_api
from apis.book_api import ns as book_api
from apis.order_api import ns as order_api
from apis import api
api.add_namespace(user_api)
api.add_namespace(book_api)
api.add_namespace(order_api)
3.下面就是 Api 的编写了。
from flask_restplus import Resource, fields, Namespace
from model import User
from apis import api
ns = Namespace("users", description="Users CURD api.")
user_model = ns.model('UserModel', {
'user_id': fields.String(readOnly=True, description='The user unique identifier'),
'username': fields.String(required=True, description='The user nickname'),
})
user_list_model = ns.model('UserListModel', {
'users': fields.List(fields.Nested(user_model)),
'total': fields.Integer,
})
@ns.route("")
class UserListApi(Resource):
# 初始化数据
users = [User("HanMeiMei"), User("LiLei")]
@ns.doc('get_user_list')
@ns.marshal_with(user_list_model)
def get(self):
return {
"users": self.users,
"total": len(self.users),
}
@ns.doc('create_user')
@ns.expect(user_model)
@ns.marshal_with(user_model, code=201)
def post(self):
user = User(api.payload['username'])
return user