Flask-RESTful自定义路由:除了GET、PUT、POST、DELETE

14 投票
3 回答
10966 浏览
提问于 2025-04-20 19:30

在Flask-RESTful中,我们可以像下面这样添加一个API路由

api.add_resource(CuteKitty,'/api/kitty')

class CuteKitty(Resource):
    def get(self): return {}
    def post(self): return {}
    def put(self): return {}
    def delete(self): return None, 204

这样一来,GET /api/kitty 就会调用 CuteKitty.get() 这个方法;其他的HTTP请求方式也是类似的

假设我想给我的API用户提供一个可爱的API,比如

POST /api/kitty/drink/milk  ---> CuteKitty.drink(what="milk")
POST /api/kitty/meow        ---> CuteKitty.meow()

我该如何使用 api.add_resource 来实现上面的路由呢

class CuteKitty(Resource):
    def get(self): return {}
    def post(self): return {}
    def put(self): return {}
    def delete(self): return None, 204
    def drink(self,what="milk"): return {}
    def meow(self): return {}

另外,如何添加像 /api/kitty/<int:kitty_id>/habits 这样的路由,让它调用 CuteKitty.habits(kitty_id)

3 个回答

0

这样做可以帮你省心,避免不必要地写出新的类,而这些方法其实应该放在同一个类里。

from flask_restful import (
    Resource,
    request
)
import logging

class AuthViews(Resource):
    logging.basicConfig(level=logging.INFO)
    logging.info("Entered the auth views...")

    def login(self):
        print("\n\t Login route....")


    def register(self):
        print("\n\t Register route....")
        

    def post(self):
        print("\n\t post-Data: ", request.data)
        print("\n\t url-Data: ", request.url)
        url = request.url
        if "login" in url:
            login = self.login()
        elif "register" in url:
            register = self.register()
        elif "forgot-password" in url:
            forgot_password = self.register()
        else:
            ...etc


完成后,你可以把和这个类相关的所有路由定义为:

auth_routes = ["/auth/login", "/auth/register", "/auth/forgot-password"]

然后在你的应用程序初始化时,你可以这样说:

app = Flask(__name__)
api = Api(app)
api.add_resource(AuthViews, *auth_routes)
2

第一步:写一个资源类。

class CuteKitty(Resource):
   def get(self): return {}
   def post(self): return {}
   def put(self): return {}
   def delete(self): return None, 204
   def meow(self): return {}

第二步:在这个类下面,或者在获取可调用对象之后,

api.add_resource(CuteKitty,'/api/kitty/meow',endpoint='meow',methods=['GET'])
23

Flask-RESTful 是一个专门用来实现 RESTful API 的工具,它主要是通过解析 HTTP 请求的方法来工作的。不过,“Drink”和“Meow”并不是标准的 HTTP 方法,所以 Flask-RESTful 对这两个方法并不关心。

解决这个问题的方法是定义多个 API 路由:

api.add_resource(CuteKitty, '/kitty/<int:kitty_id>/')
api.add_resource(DrinkingKitty, '/kitty/<int:kitty_id>/drink/<what>')
api.add_resource(MeowingKitty, '/kitty/<int:kitty_id>/meow/')

还有一种不太直观(我觉得更糟糕)的方法是创建一个“拼凑资源”:

# still allow requests to hit just get/post/etc without invoking anything else
api.add_resource(CuteKitty, '/kitty/<int:kitty_id>/')
api.add_resource(CuteKitty, '/kitty/<int:kitty_id>/<task>/<path:args>/')

然后用 split('/') 来分割参数,并用这些参数调用任务。另一种方法是把这些参数设置为 URL 参数(比如 /endpoint/?task=drink&what=milk)——这也是一种有效的 RESTful 架构。

你还可以通过继承 Resource 类来自己实现想要的功能——在这种情况下,我建议你看看 Flask-Classy 是怎么做的。或者你也可以试试 Flask-Classy,看看你是否喜欢它;不过,如果只是想做一个简单的 API,我觉得 RESTful 提供的功能会比 Classy 更强大。

撰写回答