Flask-RESTful自定义路由:除了GET、PUT、POST、DELETE
在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 个回答
这样做可以帮你省心,避免不必要地写出新的类,而这些方法其实应该放在同一个类里。
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)
第一步:写一个资源类。
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'])
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 更强大。