本系列教程分为四个阶段

1.flask restful web service

2.flask restful api

3.flask httpauth实现权限管控

4.uwsgi管理flask应用



在上一篇文章中,介绍学习了flask实现restful web services的相关内容,在此基础上,接下来我们进行关于flask的restful api的开发学习。

在web services中的学习我们认识、了解到,flask的路由定义是由Flask类实例化后的route方法进行定义,但有个问题就是我们需要在每个函数头去定义此函数对应的路由,如果我们写的是类方法,则需要在路由函数中实例化后才可实现路由控制,显然这不利于大型的项目开发中,路由的管理。

restful api的特点即是:
可独立维护flask中路由,以下是本文学习flask restful api将会了解、学习的相关模块:

from flask import Flask, jsonify, url_for, request
# from flask.ext.restful 原文中使用的此模块在python3中不适用
from flask_restful import Api, Resource, fields, marshal, reqparse, abort


其中Flask、jsonify、request、abort模块在上文中已经介绍使用过,在此不再重述。

url_for:路由跳转模块
Api:restful api模块
Resource:restful继承类
fields:数据字段自定义、重组方法
marshal:配合fields对数据字典进行遍历重组
reqparse:检索请求中的数据,判断是否符合要求


在了解相关模块信息之后,接下来进行具体的restful api开发实现。
首先我们看一下一段restful api的代码:

from flask import Flask, request
from flask_restful import Api, Resource, marshal, fields, reqparse

app = Flask(__name__)
# restful接口方法
api = Api(app)

class UserApi(Resource):

    def get(self):
        return 'get restful api data'

    def post(self):
        return 'update restful api data'

    def delete(self):
        return 'delete restful api data '

api.add_resource(UserApi, '/users', endpoint='user')

if __name__ == '__main__':
        app.run(Debug=True)

Api(app)是flask_restful调用方法,在UserApi类中继承Resource类,指明该类是符合restful api的标准类
api.add_resource则是为UserApi类定义路由的方法,其中endpoint属性是为了给该类路由定义的一个别名,默认会与类名相同,在url_for路由跳转等情况下,避免类名过长的问题,比如:

return url_for('user')

将会跳转到endpoint为user的路由方法中。

在上面的示例代码中,我们可以发现一个表现,就是UserApi类中定义了三个函数,分别为:

get() 对应HTTP get方法
post() 对应HTTP post方法
delete() 对应HTTP delete方法

在我们访问http://localhost/users 时,分别使用HTTP的三种方法看一下实际效果:
get方法:

$ curl -i 'http://localhost:5000/users'
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 23
Server: Werkzeug/1.0.1 Python/3.7.5
Date: Thu, 14 May 2020 02:06:15 GMT
"get restful api data"

post方法:

$ curl -i -X POST 'http://localhost:5000/users'
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 26
Server: Werkzeug/1.0.1 Python/3.7.5
Date: Thu, 14 May 2020 02:06:56 GMT
"update restful api data"

delete方法:

$ curl -i -X delete 'http://localhost:5000/users'
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 27
Server: Werkzeug/1.0.1 Python/3.7.5
Date: Thu, 14 May 2020 02:07:23 GMT
"delete restful api data "

以上,我们可以看出,在同一个路由中,不同的访问方法,会对应UserApi类中对应的函数名,这便是restful api中的一个便利和标准,我们无需在路由中定义HTTP请求方法,而是直接在路由类UserApi中定义对应的函数,restful api会自动解析该函数并处理返回,在大型的项目开发中,这种方式是非常便利、高效的,也在一定程度上提升了代码质量和规范性。

restful api的基础开发标准便是上面的代码示例中的方法,在实际开发中,我们会在get、post、delete函数中编写对应的数据处理方法、请求解析方法,接下来我们要学习的就是还未使用到的fields、marshal以及reqparse模块。下面看一段代码,代码中将会包含这三个模块的使用方法:


from flask import Flask
from flask_restful import Api, Resource, marshal, fields, reqparse

# 实例化flask应用
app = Flask(__name__)
# restful接口方法
api = Api(app)

users = [
    {
        'id': 1,
        'name': 'mike',
        'age': 18
    },
    {
        'id': 2,
        'name': 'suny',
        'age': 20
    }
]

user_fields = {
    'name': fields.String,
    'age': fields.Integer,
    'url': fields.Url(endpoint='user')
}

class UserApi(Resource):

    def __init__(self):
        self.reqparse = reqparse.RequestParser()
        self.reqparse.add_argument('name', type=str, required=True,
                                   help='No name provided')
        self.reqparse.add_argument('age', type=int, default="")
        super(UserApi, self).__init__()

    def get(self):
        args = self.reqparse.parse_args()
        print(args)
        for k in args:
            if args[k] != None:
                return {'user': args[k]}

    def post(self):
        return {"task": marshal(users, user_fields)}

    def delete(self):
        return 'delete restful api data '

api.add_resource(UserApi, '/users', endpoint='user')

if __name__ == '__main__':
    app.run(Debug=True)

接下来我们分别请求GET、POST方法,看一下返回信息:

# 不传参数的GET请求:
$ curl -i -X GET 'http://localhost:5000/users'
HTTP/1.0 400 BAD REQUEST
Content-Type: application/json
Content-Length: 42
Server: Werkzeug/1.0.1 Python/3.7.5
Date: Thu, 14 May 2020 02:56:33 GMT

{"message": {"name": "No name provided"}}

# 传参数的GET请求
$ curl -i -X GET -d 'name=mike' 'http://localhost:5000/users'
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 17
Server: Werkzeug/1.0.1 Python/3.7.5
Date: Thu, 14 May 2020 02:57:04 GMT

{"user": "mike"}

# POST请求
$ curl -i -X POST 'http://localhost:5000/users'
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 103
Server: Werkzeug/1.0.1 Python/3.7.5
Date: Thu, 14 May 2020 02:57:25 GMT

{"task": [{"name": "mike", "age": 18, "url": "/users"}, {"name": "suny", "age": 20, "url": "/users"}]}


观察不同请求返回结果后,可以发现我们对接口参数的请求处理及数据字典的重组分别生效,使用reqparse对接口参数进行检索,省去了我们自己在请求函数中去判断的过程,简化了代码,提高代码质量,fields+marshal模块则实现了对数据字典的重组,添加新数据并返回。


在实际应用中,以上模块均可有效的提升开发效率及代码质量,各位应在此基础上进一步的提升使用方法,此处不再展开。


其中我们在init函数中调用了super方法,即为超类调用,在存在类继承的类中,有效的解决父子类属性重复或属性修改的问题,更多的具体使用方法请查看:Python Super函数


至此关于flask的restful api的相关基础开发学习就完成了,感谢观看。