在编写web应用程序时,需要实现RESTful的api功能非常常见,当然我们可以使用flask来编写路由,实现RESTful api,但是Flask提供了便捷的方法,就是 Flask-RESTful和FLASK-RESTplus。但是相对于Flask-RESTFul, Flask-RESTplus不但可以方便的实现restful api, 同时它还集成了Swagger的文档 化功能,所有的api都会在swagger页面上展示,同时在swagger页面上也提供了对api的测试方法。
1. 安装并初始化
使用下面的命令安装flask-socketio:
$ pip install flask-restplus
接下来可以初始化flask-restplus插件:
1
2
3
4
5
6
7
8
9
10
11
12
from flask import Flask
from flask_restplus import Api
api = Api()
def create_app():
app = Flask(__name__)
app.config.from_object('app.config')
api.init_app(app)
return app
app = create_app()
2. 使用flask-restplus
接下来可以使用api对象设置一个最简单的路由:
1
2
3
4
@api.route('/hello')
class Hello(Resource):
def get(self):
return {'hello': 'world'}
Hello类继承于Resource类,其成员函数的名字和增(post),删(delete),改(put),查(get)等http方法的名字需要一样,这样在请求到来时,flask会根 据请求方法的名字来找到对应的同名的函数调用, 如果找不到,就会抛出方法未实现的异常。
启动web服务器程序,访问http://localhost:5000/hello,会得到返回的结果:
1
2
3
{
"hello": "world"
}
@api.route()装饰器也支持为资源添加多个url,这样通过这些url的访问,都会被路由到同一个资源里。比如
1
@api.route('/hello', '/world')
2.1 请求参数处理
同本身的Flask一样,flask-restplus也支持将url中的部分内容设成变量:
1
2
3
4
@api.route('/index/<string:id>')
class Index(Resource):
def get(self, id):
return {'id': '{}'.format(id)
虽然Flask提供了request.form来接收post请求的参数,但是验证表单数据仍然非常头疼,需要借助使用flask-wtform插件完成。而flask-restplus内置 了对请求数据的验证功能,通过reqparse实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
parser = reqparse.RequestParser()
parser.add_argument('data', type=int, required=True, help='data should be int')
parser.add_argument('id', type=int, required=True, help='id should be int')
@api.route('/index')
class Index(Resource):
def get(self):
return {'id': '{}'.format(id)}
def post(self):
args = parser.parse_args()
data, id = args['data'], args['id']
return {'data': data, 'id': id}
当data和id两个参数传递的值不满足上面要求时,验证不通过,同时会在网页端显示help里定义的信息。
2.2 返回数据格式化
上面的例子里,所有请求方法定义的函数返回值都是python内置的数据结构,它些对象可以直接被序列化后原样返回。但是如果我们需要返回一个自定义的类对象 的时候,就需要使用@api.marshal_with装饰器做特殊处理,否则会报错, 看个例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
model = api.model('Model', {
'id': fields.String,
'task': fields.String
})
class Dao():
def __init__(self, id, task):
self.id = id
self.task = task
self.status = 'done' # 这个定不会返回,使用了marshal_with, 就只api.model里写明的数据
@api.route('/todo')
class Todo(Resource):
@api.marshal_with(model)
def get(self):
return Dao(id='1', task='drink milk')
当访问http://localhost:5000/todo时,会返回
1
2
3
4
{
"id": "1",
"task": "drink milk"
}
如果没有使用@api.marshal_with()这个装饰器,这次请求就会报错。也可以使用marshal()方法来替代@api.marshal_with()装饰器:
1
2
3
4
@api.route('/todo')
class Todo(Resource):
def get(self):
return marshal(Dao(id='1', task='drink milk'), model)
有时候,我们需要返回的字段名可能和真实的字段名不一样,这个时候可以通过attribute传递真实的字段名实现。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
model = api.model('Model', {
'idx': fields.String(attribute='id'), # 使用attribute做了一次字段名字映射
'task': fields.String
})
``·
### 2.3 内置Swagger
Swagger是一个规范和完整的框架,用于生成、描述、调用和可视化RESTful风格的 Web 服务。主要是为了方便RESTful api的接口文档在线生成,并且方便
直接在网页端对restful api进行在线测试。flask-restplus里集成了swagger的功能。直接访问服务器的root url就会打开swagger的前端页面。显示
效果如下:

可以为整个类或者某一个方法添加@api.doc()装饰器使api在swagger页面里可以具体的显示每个参数的类型以及返回码信息。默认的在swagger里只有200这一个
返回码。
@api.route(‘/hello’) @api.doc(params={‘id’: ‘An ID’}) class Hello(Resource): def get(self): return {‘hello’: ‘world’}
1
2
3
@api.doc(responses={403: 'Not Authorized'})
def post(self, id):
api.abort(403) ```
同时,上一节中,使用@api.marshal_with()标明的返回数据格式,也会在Swagger页面展示出来。
想要获取完整代码,请点击这里