我正在使用CherryPy 3制作RESTful WebService但我遇到了一个问题: 我希望能够回答以下请求: / customers / 1 / products / 386 表示我想要ID为1的客户ID为386的所有产品。
所以我尝试使用CherryPy的MethodDispatcher这样做:
class UserController(object):
exposed = True
def __init__(self):
self.product = ProductController()
@log_io
def GET(self, *args):
return "GET Users :" + str(args)
class ProductController(object):
exposed = True
@log_io
def GET(self, *args):
return "GET Product :" + str(args)
但是当我请求/ customers / 1 / products / 386时,不是使用正确的参数将我重定向到ProductController.GET,而是使用参数1,“products”,386将我重定向到UserController.GET。
要重定向到ProductController.GET我必须查询/ customers / products / 386这是不正确的,因为我错过了用户ID参数。
我在这个演示文稿中看到:RESTful Web Applications with CherryPy我想要使用的路径样式似乎是一个不错的选择。但有没有一种简单的方法来实现Cherry Py?
我听说过CherryPy 3的_cp_dispatch方法,但我不知道它到底是什么以及如何使用它。它是否取代了MethodDispatcher?
答案 0 :(得分:22)
CherryPy使用基于树的映射器,它不能很好地适应没有物理现实的段作为Python对象,这里是你的/ 1 /段。
据说,CherryPy确实提供了实现目标的功能。
让我们关注最后两个。
_cp_dispatch是一种特殊方法,您可以在任何控制器中声明,以便在CherryPy处理它们之前按下剩余的段。这使您能够移除,添加或以其他方式处理您希望的任何细分,甚至完全更改其余部分。
import cherrypy
class Band(object):
def __init__(self):
self.albums = Album()
def _cp_dispatch(self, vpath):
if len(vpath) == 1:
cherrypy.request.params['name'] = vpath.pop()
return self
if len(vpath) == 3:
cherrypy.request.params['artist'] = vpath.pop(0) # /band name/
vpath.pop(0) # /albums/
cherrypy.request.params['title'] = vpath.pop(0) # /album title/
return self.albums
return vpath
@cherrypy.expose
def index(self, name):
return 'About %s...' % name
class Album(object):
@cherrypy.expose
def index(self, artist, title):
return 'About %s by %s...' % (title, artist)
if __name__ == '__main__':
cherrypy.quickstart(Band())
cherrypy.popargs更直接,因为它为CherryPy无法解释的任何段命名。这使得段与页面处理程序签名的匹配更容易,并帮助CherryPy理解URL的结构。
import cherrypy
@cherrypy.popargs('name')
class Band(object):
def __init__(self):
self.albums = Album()
@cherrypy.expose
def index(self, name):
return 'About %s...' % name
@cherrypy.popargs('title')
class Album(object):
@cherrypy.expose
def index(self, name, title):
return 'About %s by %s...' % (title, name)
if __name__ == '__main__':
cherrypy.quickstart(Band())
在这两种情况下,请转到http://whatevertomakesohappy.com:8080/nirvana/,然后转到http://whatevertomakesohappy.com:8080/nirvana/albums/nevermind/
两者都很强大,但您想要使用哪一个取决于您。对于简单的URL,popargs在我的书中可能会容易得多。显然两者都可以同时使用。
答案 1 :(得分:5)
感谢您的回答Sylvain。你引导我找到了我想要的答案。 我像这样使用RouteDispatcher:
self.connect("cust_products", "/customers/{cust_id}/products/",
controller=CustomerController(),
action='index',
conditions=dict(method=['GET']))
self.connect("cust_products", "/customers/{cust_id}/products/{id}",
controller=CustomerController(),
action='show',
conditions=dict(method=['GET']))
self.connect("cust_products", "/customers/{cust_id}/products/",
controller=CustomerController(),
action='create',
conditions=dict(method=['POST']))
self.connect("cust_products", "/customers/{cust_id}/products/{id}",
controller=CustomerController(),
action='update',
conditions=dict(method=['PUT']))
self.connect("cust_products", "/customers/{cust_id}/products/{id}",
controller=CustomerController(),
action='delete',
conditions=dict(method=['DELETE']))