首页 > 解决方案 > 单独的资源链接 Flask Restful API

问题描述

我正在学习 Flask Restful API,在学习一些教程时我遇到了一个示例

class Student(Resource):
def get(self):
    return {student data}

def post(self, details):
    return {data stored}

api.add_resource(Student,'/student')

在这里,看上面的例子,我们可以使用 /student 和 GET、POST 方法来检索和存储数据。但我希望有 2 个不同的端点用于检索和存储数据,每个端点。例如

/student/get

它将调用 Student 类的 get() 函数,以检索所有学生的记录,以及

/student/post

它将调用 Student 类的 post() 函数来存储发送/发布的数据。

是否可以有一个学生班级但调用不同端点引用的不同方法。

标签: pythonapirestflaskflask-restful

解决方案


是的,可以有一个Resource类但调用不同端点引用的不同方法。

设想:

  • 我们有一个Student带有getandpost方法的类。
  • 我们可以使用不同的路由单独或组合执行getand方法。post
  • 例如:
    • Endpointhttp://localhost:5000/students/get只能用于类的get请求Student
    • Endpointhttp://localhost:5000/students/post只能用于类的post请求Student
    • Endpointhttp://localhost:5000/students/可用于类的get, 和post请求Student

解决方案:

  • 为了控制资源类中不同的端点请求,我们需要传递一些关键字参数给它。
  • 我们将使用方法resource_class_kwargs的选项add_resource。详细信息add_resource可以在官方文档中找到
  • 我们将使用方法阻止任何不需要的方法调用abort。对于端点中不需要的方法调用,我们将返回405带有响应消息的 HTTP 状态。Method not allowed

代码:

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

app = Flask(__name__)
api = Api(app)

parser = reqparse.RequestParser()
parser.add_argument('id', type=int, help='ID of the student')
parser.add_argument('name', type=str, help='Name of the student')



def abort_if_method_not_allowed():
    abort(405, message="Method not allowed")

students = [{"id" : 1, "name": "Shovon"},
            {"id" : 2, "name": "arsho"}]

class Student(Resource):
    def __init__(self, **kwargs):
        self.get_request_allowed = kwargs.get("get_request_allowed", False)
        self.post_request_allowed = kwargs.get("post_request_allowed", False)
        
    def get(self):
        if not self.get_request_allowed:
            abort_if_method_not_allowed()
        return students

    def post(self):
        if not self.post_request_allowed:
            abort_if_method_not_allowed()
        student_arguments = parser.parse_args()
        student = {'id': student_arguments['id'],
                   'name': student_arguments['name']}
        students.append(student)
        return student, 201


api.add_resource(Student, '/students', endpoint="student",
                 resource_class_kwargs={"get_request_allowed": True, "post_request_allowed": True})
api.add_resource(Student, '/students/get', endpoint="student_get",
                 resource_class_kwargs={"get_request_allowed": True})
api.add_resource(Student, '/students/post', endpoint="student_post",
                 resource_class_kwargs={"post_request_allowed": True})

预期行为:

  • curl http://localhost:5000/students/get应该调用类的get方法Student
  • curl http://localhost:5000/students/post -d "id=3" -d "name=Sho" -X POST -v应该调用类的post方法Student
  • curl http://localhost:5000/students可以调用 Student类的两个方法。

测试:

  • 我们将调用我们登记的端点并测试每个端点的行为是否符合预期。
  • 使用中的get请求输出:students/getcurl http://localhost:5000/students/get
    [
        {
            "id": 1,
            "name": "Shovon"
        },
        {
            "id": 2,
            "name": "arsho"
        }
    ]
  • 使用中的post请求输出:students/postcurl http://localhost:5000/students/post -d "id=3" -d "name=Shody" -X POST -v
    {
        "id": 3,
        "name": "Shody"
    }
  • students使用中获取请求的输出curl http://localhost:5000/students
    [
        {
            "id": 1,
            "name": "Shovon"
        },
        {
            "id": 2,
            "name": "arsho"
        },
        {
            "id": 3,
            "name": "Shody"
        }
    ]
  • 使用中的post请求输出:studentscurl http://localhost:5000/students -d "id=4" -d "name=Ahmedur" -X POST -v
    {
        "id": 4,
        "name": "Ahmedur"
    }
  • 使用中的post请求输出:students/getcurl http://localhost:5000/students/get -d "id=5" -d "name=Rahman" -X POST -v
    {
        "message": "Method not allowed"
    }
  • 使用中的get请求输出:students/postcurl http://localhost:5000/students/post
    {
        "message": "Method not allowed"
    }

参考:


推荐阅读