【Flask Framework】—— 30 Flask-RESTful

insert image description here

insert image description here


Separation of front and rear ends and non-separation of front and rear ends

In the application mode where the front and back ends are not separated
, the effect seen on the front-end page is controlled by the back-end, and the page is rendered or redirected by the back-end, that is, the back-end needs to control the display of the front-end, and the front-end and back- end The degree of coupling is high .

This application mode is more suitable for pure web applications, but when the backend is connected to the App, the App may not need the backend to return an HTML webpage, but only the data itself, so the interface that the backend originally returned to the webpage is no longer applicable to the frontend App application, in order to connect to the backend of the App, another set of interfaces needs to be developed.
Separation of front-end and back- end In the application mode of separation of front-end and back-end, the back-end only returns the data
required by the front-end , no longer renders HTML pages, and no longer controls the effect of the front-end. As for what effect the front-end user sees, how the data requested from the back-end is loaded into the front-end is determined by the front-end itself. Web pages have the processing methods of web pages, and Apps have the processing methods of Apps. Basically the same, the backend only needs to develop a set of logic to provide data to the outside world.

In the application mode where the front-end and the back-end are separated, the coupling between the front-end and the back-end is relatively low.

In the application mode where front-end and back-end are separated, we usually refer to each view developed by the back-end as an interface, or API, and the front-end accesses the interface to add, delete, modify, and query data.

1. Definition of RESTful

RESTfulIt is a design style and development method of network applications, based on HTTP, which can be defined in XML format or JSON format. RESTfulApplicable to scenarios where mobile Internet vendors serve as service enabling interfaces.

insert image description here

RESTFUL features include:
1. Each URI represents a resource;

2. The client uses GET, POST, PUT, and DELETE to operate on server resources: GETto obtain resources, POSTto create new resources (also used to update resources), PUTto update resources, DELETEto delete resources;

3. Operate resources by manipulating the manifestation of resources;

4. The form of resource is XMLor JSON;

5. The interaction between the client and the server is stateless between requests, and each request from the client to the server must contain the information necessary to understand the request.

2. RESTful style software architecture

The RESTful architecture is an architecture formed after the improvement of the MVC architecture, and is connected with different services by using a pre-defined interface. In the RESTful architecture, the client uses POST, DELETE, PUTand GETfour request methods to add, delete, modify, and query the specified URLresources respectively. Therefore, RESTful realizes the management and access to resources through URI, which has the characteristics of strong scalability and clear structure.

The RESTful architecture divides the server into two parts, the front-end server and the back-end server. The front-end server provides users with a model-free view; the back-end server provides an interface for the front-end server. The browser requests the view from the front-end server, and initiates an interface request to obtain the model through the AJAX function contained in the view.

The project development introduces the RESTful architecture, which is conducive to the parallel development of the team. In the RESTful architecture, most HTTP requests are transferred to the front-end server to reduce the load on the server, so that the view can be presented even if it fails to obtain the back-end model. However, the RESTful architecture is not suitable for all projects. When the project is relatively small, there is no need to use the RESTful architecture, and the project becomes more complicated.

3. Installation and use

1. Install

pip install flask-restful

insert image description here

2. Normal use

from flask import Flask
from flask_restful import Api, Resource

app = Flask(__name__)
# 需求,对外提供一个API接口,可以访问某个资源
# 步骤一:创建restful的API
api = Api(app)


# 步骤二,定义资源resource
class HelloResource(Resource):

    # 定义各种操作(函数)
    def get(self):
        return {
    
    'get': 'get'}

    def put(self):
        return {
    
    'put': 'put'}

    def post(self):
        return {
    
    'post': 'post'}


# 步骤三:把资源加载到Api中才能对外发布
api.add_resource(HelloResource, '/hello')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8888, debug=True)

2. Blueprint usage

# -*- coding: utf-8 -*-
from flask import Flask, Blueprint
from flask_restful import Api, Resource

bp = Blueprint('user', __name__)
app = Flask(__name__)

# 需求,对外提供一个API接口,可以访问某个资源
# 步骤一:创建restful的API
api = Api(bp)


# 步骤二,定义资源resource
class HelloResource(Resource):

    # 定义各种操作(函数)
    def get(self):
        return {
    
    'get': 'get'}

    def put(self):
        return {
    
    'put': 'put'}

    def post(self):
        return {
    
    'post': 'post'}


# 步骤三:把资源加载到Api中才能对外发布
api.add_resource(HelloResource, '/hello')

# 注册蓝图
app.register_blueprint(bp, url_prefix='/user')
# 注意:当前情况下api的接口访问地址 = 蓝图的url_prefix + 资源请求的路径


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8888, debug=True)

Note: If there is one in the blueprint url_prefix, then requesturl = url_prefix + resource_url

Four, Request and RequestParser class

1. RequestParser class

Flask-RESTful provides the RequestParser class to help us inspect and transform request data.

from flask_restful import reqparse

def post(self):
    # 1.创建请求参数校验的对象requestParser
    rq = reqparse.RequestParser()

    # 2.定义参数的校验申明
    rq.add_argument('a', required=True, location='args')

    # 3.启动校验
    req = rq.parse_args()
    # 4.校验完后得到参数的值
    a = req.a
    return {
    
    'post': 'post', "a": a}

insert image description here

Steps for usage:

  1. Create a request parameter validation RequestParserobject .
  2. Add parameter declarations that require validation or conversion to RequestParserthe object .
  3. Use parse_args()the method to start validation processing.
  4. After the inspection, parameters can be obtained from the inspection results according to dictionary operation or object attribute operation.

2. Parameter description

1、required

Describe whether the request must carry corresponding parameters, the default value is False

  • True is mandatory to carry.
    If not carried, the verification fails and an error message is returned to the client with status code 400

  • False It is not mandatory to carry.
    If it is not mandatory, when the client request does not carry parameters, the fetched value is None

2. help
The error description information returned when the parameter inspection error

3. action
Describe the processing method when multiple parameters with the same name appear in the request parameters.
action='store'Keep the first one that appears, and
action='append'save the values ​​of all parameters with the same name in a list by default.

4、choices

rq.add_argument('c', type=str, choices=['男', '女'], action='append', location='args')

5. type
To describe the type that the parameter should match, you can use python's standard data types string and int, or use the inspection method provided by Flask-RESTful, or define it yourself.
standard type

rq.add_argument('b', type=str, required=True, action='append', location='args')

Flask-RESTful provides
the check type method in flask_restful.inputsthe module

  • url
  • regex(指定正则表达式)
  • natural natural numbers 0, 1, 2, 3…
  • positive Positive integer 1, 2, 3...
  • int_range(low ,high)integer range
  • boolean Boolean type

6. location
Describe where the parameter should appear in the request data

# Look only in the POST body 表单
parser.add_argument('name', type=int, location='form')

# Look only in the querystring 请求地址?后面的参数
parser.add_argument('PageSize', type=int, location='args')

# From the request headers  请求头
parser.add_argument('User-Agent', location='headers')

# From http cookies
parser.add_argument('session_id', location='cookies')

# From json
parser.add_argument('user_id', location='json')

# From file uploads  文件提交
parser.add_argument('picture', location='files')

You can also specify multiple locations, brackets [ ]

parser.add_argument('text', location=['headers', 'json'])
# -*- coding: utf-8 -*-

from flask import Flask
from flask_restful import Api, Resource, reqparse, inputs

app = Flask(__name__)
# 需求,对外提供一个API接口,可以访问某个资源
# 步骤一:创建restful的API
api = Api(app)


# 步骤二,定义资源resource
class HelloResource(Resource):

    # 定义各种操作(函数)
    def get(self):
        return {
    
    'get': 'get'}

    def put(self):
        return {
    
    'put': 'put'}

    def post(self):
        # 1.创建请求参数校验的对象requestParser
        rq = reqparse.RequestParser()

        # 2.定义参数的校验申明
        rq.add_argument('a', type=int, required=True, help='参数a错误', location='args')
        # 如果定义help,那么所有的校验只有一种
        rq.add_argument('b', type=str, required=True, action='append', location='args')
        rq.add_argument('c', type=str, choices=['男', '女'], action='append', location='args')
        rq.add_argument('d', type=inputs.regex('^\d{2}$'), location='args')  # 只允许两位整数
        rq.add_argument('e', type=inputs.int_range(1, 100), location='args')  # 允许范围内
        rq.add_argument('f', type=inputs.boolean)  # 只允布尔类型
        # 3.启动校验
        req = rq.parse_args()
        # 4.校验完后得到参数的值
        a = req.a
        b = req.b
        c = req.c
        d = req.d
        return {
    
    "a": a, 'b': b, 'c': c, 'd': d}


# 步骤三:把资源加载到Api中才能对外发布
api.add_resource(HelloResource, '/hello')


# app.run可以省略
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8888, debug=True)

insert image description here


Five, RESTful response processing

1. Serialized data

Flask-RESTfulTools are provided marshalto help us serialize data into dictionary data in a specific format, so that it can be used as the return value of the view.

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

app = Flask(__name__)
# 需求,对外提供一个API接口,可以访问某个资源
# 步骤一:创建restful的API
api = Api(app)


class User(object):
    def __init__(self, username, passwd, user_id):
        self.uname = username
        self.pwd = passwd
        self.id = user_id


# 为了把模型对象转换为字典,在marshal里面必须定义一个属性转换格式
property_fields = {
    
    
    'pwd': fields.String,
    'uname': fields.String
}


# 步骤二,定义资源resource
class HelloResource(Resource):

    # 定义各种操作(函数)
    @marshal_with(fields=property_fields, envelope='user01')
    def get(self):  # 获取
        u = User('zhang san', '123123', 1)
        return u

    def put(self):  # 更新
        return {
    
    'put': 'put'}

    def post(self):  # 新建资源
        return {
    
    'post': 'post'}


# 步骤三:把资源加载到Api中才能对外发布
api.add_resource(HelloResource, '/hello')


# app.run可以省略
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8888, debug=True)

It is also possible to use no decorator

class HelloResource(Resource):

    # @marshal_with(fields=property_fields, envelope='user01')
    def get(self, **kwargs):  # 获取
        u = User('zhang san', '123123', 1)
        return marshal(u, property_fields, envelope='user01')

2. Customize the returned JSON format

Requirements: You want the JSON data returned by the interface to have the following unified format

{
    
    "message": "描述信息", "data": {
    
    要返回的具体数据}}

When the interface processing is normal, the message can return ok, but if you want each interface to return correctly, omit the message field

u = User('zhang san', '123123', 1)

For interfaces like this, can they be uniformly formatted into the above-mentioned required format somewhere?

{
    
    
    "message": "OK",
    "data": {
    
    
        "pwd": "123123",
        "uname": "zhang san"
    }
}

The object that solves
Flask_RESTful Apiprovides a representationdecorator that allows customizing the presentation format of the returned data

@api.representation('application/json')
def output_json(data, code, headers=None):
    """Makes a Flask response with a JSON encoded body"""

    # 此处添加自己定义的json格式规则
    if 'message' not in data:
        data = {
    
    'message': 'OK',
                'data': data}

Flask-RESTful's original processing method for json format is as follows:
insert image description here

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

from flask import make_response, current_app
from flask_restful.utils import PY3
from json import dumps

app = Flask(__name__)
# 需求,对外提供一个API接口,可以访问某个资源
# 步骤一:创建restful的API
api = Api(app)


class User(object):
    def __init__(self, username, passwd, user_id):
        self.uname = username
        self.pwd = passwd
        self.id = user_id


# 为了把模型对象转换为字典,在marshal里面必须定义一个属性转换格式
property_fields = {
    
    
    'pwd': fields.String,
    'uname': fields.String
}


@api.representation('application/json')
def output_json(data, code, headers=None):
    """Makes a Flask response with a JSON encoded body"""

    # 此处添加自己定义的json格式规则
    if 'message' not in data:
        data = {
    
    'message': 'OK',
                'data': data}

    settings = current_app.config.get('RESTFUL_JSON', {
    
    })

    # If we're in debug mode, and the indent is not set, we set it to a
    # reasonable value here.  Note that this won't override any existing value
    # that was set.  We also set the "sort_keys" value.
    if current_app.debug:
        settings.setdefault('indent', 4)
        settings.setdefault('sort_keys', not PY3)

    # always end the json dumps with a new line
    # see https://github.com/mitsuhiko/flask/pull/1262
    dumped = dumps(data, **settings) + "\n"

    resp = make_response(dumped, code)
    resp.headers.extend(headers or {
    
    })
    return resp


# 步骤二,定义资源resource
class HelloResource(Resource):

    # 定义各种操作(函数)
    # @marshal_with(fields=property_fields, envelope='user01')
    def get(self, **kwargs):  # 获取
        u = User('zhang san', '123123', 1)
        return marshal(u, property_fields)

    def put(self):  # 更新
        return {
    
    'put': 'put'}

    def post(self):  # 新建资源
        return {
    
    'post': 'post'}


# 步骤三:把资源加载到Api中才能对外发布
api.add_resource(HelloResource, '/hello')


# app.run可以省略
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8888, debug=True)

insert image description here


Guess you like

Origin blog.csdn.net/m0_68744965/article/details/128533396