Flask扩展系列1--Restful
1、首先了解什么是restful
架构?
rest
:representational state transfer表现层状态转化
资源
:网络上的一个实体,或者说一个具体的信息。每种资源对应一个特定的URI,要获取这个资源,就是访问这个URI就可以
表现层
:representation 把资源呈现出来的形式,叫做表现层,在HTTP请求的头信息中用Accept和Content-Type字段指定,是对“表现层”的描述
状态转化
:客户端想要操作服务器,必须通过某种手段,让服务器发生状态转化,有GET
、POST
、PUT
、DELETE
四种方式,其中GET
是用来获取资源,POST
是用来新建资源(也可以进行更新资源),PUT
用来更新资源,DELETE
用来删除资源
所以restful架构是:
1)每一个URI代表一个资源;
2)客户端和服务器之间,传递这种资源的某种表现层;
3)客户端通过四个HTTP动词,对服务器端资源进行操作,实现“表现层状态转化”;
误区:最常见的一种设计错误,就是URI中包含动词。因为“资源”表示一种实体,所以应该是名词,URI不应该有动词,动词应该放到HTTP协议中
2、Flask-RESTful基本请求
from flask import Flask, request
from flask_restful import Api, Resource
app = Flask(__name__)
api = Api(app)
USER_LIST = {
'1': {'name': 'Michael'},
'2': {'name': 'Tom'}
}
class UserList(Resource):
def get(self):
return USER_LIST
def post(self):
user_id = int(max(USER_LIST.keys())) + 1
user_id = str(user_id)
USER_LIST[user_id] = {'name': request.form['name']}
return USER_LIST
api.add_resource(UserList, '/users')
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
其中一个接口有两种请求方式,一个是get,另一个是post。
get返回USER_LIST这个json数据;
post需要传一个参数,然后返回整个USER_LIST,请求一次post方法就会多添加一次数据,如果post请求中找不到name字段,则返回“400 Bad Request”错误;
由于类UserList没有定义put()和delete()函数,所以在”PUT”或”DELETE”请求时会返回”405 Method Not Allowed”错误。
其中在postman中是这么进行传递的
GET请求
POST请求
image.png
另外,路由支持多个路径,比如:
api.add_resource(UserList, '/userlist', '/users')
访问userlist和users两个路径的效果完全一样
3、带参数的请求
上面的例子中我们都是针对USER_LIST这个列表的,如果我们需要针对具体的user进行操作呢,就需要传递具体的user_id了,这时候,我们就需要路由支持带参数。
from flask import Flask, request
from flask_restful import Api, Resource
app = Flask(__name__)
api = Api(app)
USER_LIST = {
'1': {'name': 'Michael'},
'2': {'name': 'Tom'}
}
class User(Resource):
def get(self, user_id):
return USER_LIST[user_id]
def delete(self, user_id):
del USER_LIST[user_id]
return ''
def post(self, user_id):
USER_LIST[user_id] = {'name': request.form['name']}
return USER_LIST
api.add_resource(User, '/users/<user_id>')
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
在User类的get(),post(),put()等成员函数中,记得加上参数user_id来获取传入的变量值
4、参数解析
在“POST”和“PUT”请求中,直接访问form表单并验证的工作有些麻烦,Flask-RESTful提供了 reqparse库来简化,可以通过parser.add_argument()
方法来定义form表单字段,并指定其类型,然后在put或者post函数中调用parser.parse_args()
来获取表单内容,并返回一个字典,该字典就包含表单的内容。parser.parse_args()
方法会自动验证数据类型,返回400错误,还可以添加strict参数,如parser.parse_args(strict=True)
,此时出现为定义的参数,也会返回400错误
from flask import Flask
from flask_restful import Api, Resource, reqparse, abort
app = Flask(__name__)
api = Api(app)
USER_LIST = {
'1': {'name': 'Michael'},
'2': {'name': 'Tom'}
}
parser = reqparse.RequestParser()
parser.add_argument('name', type=str)
def abort_if_not_exist(user_id):
if user_id not in USER_LIST:
abort(404, message='User {} does not exist'.format(user_id))
class User(Resource):
def get(self, user_id):
abort_if_not_exist(user_id)
return USER_LIST[user_id]
def delete(self, user_id):
abort_if_not_exist(user_id)
del USER_LIST[user_id]
return '', 204
def post(self, user_id):
args = parser.parse_args(strict=True)
USER_LIST[user_id] = {'name': args['name']}
return USER_LIST, 201
class UserList(Resource):
def get(self):
return USER_LIST
def post(self):
args = parser.parse_args(strict=True)
user_id = str(int(max(USER_LIST.keys())) + 1)
USER_LIST[user_id] = {'name': args['name']}
return USER_LIST, 201
api.add_resource(User, '/users/<user_id>')
api.add_resource(UserList, '/users')
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)