带有CherryPy的REST Web服务的友好URL [英] Friendly URL for a REST WebService with CherryPy
问题描述
我正在使用CherryPy 3创建RESTful WebService,但是遇到一个问题:我希望能够回答以下要求:/customers/1/products/386 表示我想要ID为1的客户端的所有ID为386的产品.
所以我尝试使用CherryPy的MethodDispatcher来做到这一点:
Class UserController(object):暴露=真def __init __():self.product = ProductController()@log_io定义GET(self,* args):返回获取用户:" + str(args)类ProductController(object):暴露=真@log_io定义GET(self,* args):返回获取产品:" + str(args)
但是,当我请求/customers/1/products/386时,没有使用正确的参数将我重定向到ProductController.GET,而是使用参数1,"products",386将我重定向到UserController.GET.
要重定向到ProductController.GET,我必须查询/customers/products/386,这是不正确的,因为我错过了用户ID参数.
我在此演示文稿上看到过:使用CherryPy的RESTful Web应用程序想要使用似乎是一个不错的选择.但是,有没有一种简单的方法可以用Cherry Py实现它?
我听说过CherryPy 3的_cp_dispatch方法,但我不知道它到底是什么以及如何使用它.它可以代替MethodDispatcher吗?
CherryPy使用基于树的映射器,无法很好地适应那些没有物理现实的段作为Python对象,这里是您的/1/段.>
话虽如此,CherryPy确实提供了实现您目标的功能.
- 切换到更明确的映射器,例如选择器或
cherrypy.popargs更直接,因为它为CherryPy否则无法解释的任何段命名.这使段与页面处理程序签名的匹配更加容易,并帮助CherryPy了解您的URL的结构.
导入cherrypy@ cherrypy.popargs('名称')Band(对象)类:def __init __():self.albums =专辑()@ cherrypy.exposedef索引(自身,名称):返回关于%s ..."的%名称@ cherrypy.popargs('标题')类Album(object):@ cherrypy.exposedef索引(自身,名称,标题):返回关于%s的%s ..."%(标题,名称)如果__name__ =='__main__':cherrypy.quickstart(Band())
在两种情况下,请先访问 http://whatevertomakesohappy.com:8080/nirvana/,然后访问http://whatevertomakesohappy.com:8080/nirvana/albums/nevermind/
两者都很强大,但是您要使用哪一个取决于您.对于简单的URL,popargs在我的书中可能会容易得多.显然,两者可以同时使用.
I'm making a RESTful WebService using CherryPy 3 but I encounter a problem : I want to be able to answer requests like : /customers/1/products/386 meaning I want all the product with ID 386 of the client with ID 1.
So I try to make it with the CherryPy's MethodDispatcher like this :
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)
But when I request /customers/1/products/386, instead of redirecting me to ProductController.GET with the right parameters, it redirects me to UserController.GET with the parameters 1, "products", 386.
To be redirected to ProductController.GET I have to query /customers/products/386 which is incorrect because I miss the user ID parameter.
I've seen on this presentation : RESTful Web Applications with CherryPy that the path style I want to use seems to be a good choice. But is there an easy way to implement it with Cherry Py ?
I've heard about the _cp_dispatch method of CherryPy 3 but I don't get exactly what it is and how to use it. Does it replace the MethodDispatcher ?
解决方案CherryPy uses a tree-based mapper which does not accommodate well with segments that have no physical reality as a Python object, here your /1/ segment.
With that said, CherryPy does provide functionalities to reach your goal.
Let's focus on the last two.
_cp_dispatch is a special method you declare in any of your controller to massage the remaining segments before CherryPy gets to process them. This offers you the capacity to remove, add or otherwise handle any segment you wish and, even, entirely change the remaining parts.
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 is more straightforward as it gives a name to any segment that CherryPy wouldn't be able to interpret otherwise. This makes the matching of segments with page handler signatures easier and help CherryPy understand the structure of your 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())
In both cases go to http://whatevertomakesohappy.com:8080/nirvana/ and then http://whatevertomakesohappy.com:8080/nirvana/albums/nevermind/
Both are powerful but which one you want to use is up to you. For simple URLs, popargs is likely to be much easier in my book. Obviously both can be used concurrently.
这篇关于带有CherryPy的REST Web服务的友好URL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!