一个处理程序可以在龙卷风中处理发布和获取请求(URL稍有不同)吗?
例如,我想要拥有:
undefined
使用请求中的数据创建新用户
身体/app/user (POST)
返回具有给定ID的用户目前,我有两个处理程序/app/user/<user_id> (GET)
和GetUser
和两条路由。
答案 0 :(得分:1)
是的,您可以执行此操作,但是到目前为止,我所见过的所有快速解决方案在处理位置参数时总是会有一些不便之处。看一下这个例子:
import tornado.ioloop
import tornado.web
class UserHandler(tornado.web.RequestHandler):
def get(self, __):
self.write("Get request")
def post(self, user_id):
self.write(f"Post request for user id {user_id}")
app = tornado.web.Application([
(r"/app/user/?(\d+)?", UserHandler),
])
app.listen(8000)
tornado.ioloop.IOLoop.current().start()
这将建立一个匹配两个URL模式并分配UserHandler
的路由规则。 URL中的捕获组是可选的,因此当POST请求发送到None
时,user_id
可能作为/app/user
传递。使用这种方法,龙卷风将始终使用正则表达式中第二组的参数调用get
方法。根据您的项目,您可能需要进行更广泛的错误检查(检查给定的参数,如果不是None
,则发送405 Method Not Allowed
或适合您情况的任何方法-也许您想要允许一个用户使用GET?)
也可以通过使用同一处理程序添加两个规则来做到这一点:
import tornado.ioloop
import tornado.web
class UserHandler(tornado.web.RequestHandler):
def get(self):
self.write("Get request")
def post(self, user_id):
self.write(f"Post request for user id {user_id}")
app = tornado.web.Application([
(r"/app/user", UserHandler),
(r"/app/user/(\d+)", UserHandler),
])
app.listen(8000)
tornado.ioloop.IOLoop.current().start()
请记住,龙卷风的POST和GET请求都将匹配这两个路线,这带来了不便:
/app/user
发送POST请求,则会抛出TypeError: post() missing 1 required positional argument: 'user_id'
。/app/user/123
发送GET请求,则会抛出TypeError: get() takes 1 positional argument but 2 were given
您可以解决这些问题,但是我认为第一种解决方案可以更简洁地解决此问题。
编辑:当然,您还可以实现自己的Matcher
类,该类不仅可以通过子类化tornado.routing.PathMatches
来区分URL,而且可以区分请求方法-尽管这是一些代码。这里的主要缺点是对于有效的路由,服务器将在应为405s的位置返回404响应(因为路由/“资源”本身是有效的,所以方法错误)
import tornado.ioloop
import tornado.web
import tornado.routing
class MethodAndPathMatch(tornado.routing.PathMatches):
def __init__(self, method, path_pattern):
super().__init__(path_pattern)
self.method = method
def match(self, request):
if request.method != self.method:
return None
return super().match(request)
class UserHandler(tornado.web.RequestHandler):
def get(self):
self.write("Get request")
def post(self, user_id):
self.write(f"Post request for user id {user_id}")
app = tornado.web.Application([
(MethodAndPathMatch("GET", r"/app/user"), UserHandler),
(MethodAndPathMatch("POST", r"/app/user/(\d+)"), UserHandler),
])
app.listen(8000)
tornado.ioloop.IOLoop.current().start()
cURL进行测试:
$ curl -w '\n' -X POST localhost:8000/app/user
$ curl -w '\n' -X POST localhost:8000/app/user/123
$ curl -w '\n' -X GET localhost:8000/app/user
$ curl -w '\n' -X GET localhost:8000/app/user/123
答案 1 :(得分:-1)
简单
def options(self):
return
get=head=post=delete=patch=put=options