2010-04-26 96 views
12

在CherryPy中创建REST风格的Web API的最佳方法是什么?我一直在四处寻找,没有什么看起来很棒。对于Django来说,似乎有很多工具可以做到这一点,但对于CherryPy来说不是这样,或者我不知道它们。CherryPy和REST风格的Web API

后来编辑:我应该如何使用CherryPy的像/ getOrders占= X &类型= Y变换的请求弄成/命令/帐号/类型?

回答

1

我假设你已经尝试了部分匹配,就像本教程中讨论的一样。我发现虽然不是很好,但它大部分时间完成了工作。

除此之外,虽然我没有尝试过,但Cherrypy显然支持Routes(请参阅http://www.cherrypy.org/wiki/PageHandlers),它为您提供了各种RESTful选项。

+0

不工作的链接:( – 2018-01-25 09:40:18

11

我不知道这是否是“最佳”的方式,但在这里就是我如何做到这一点:

import cherrypy 

class RESTResource(object): 
    """ 
    Base class for providing a RESTful interface to a resource. 

    To use this class, simply derive a class from it and implement the methods 
    you want to support. The list of possible methods are: 
    handle_GET 
    handle_PUT 
    handle_POST 
    handle_DELETE 
    """ 
    @cherrypy.expose 
    def default(self, *vpath, **params): 
     method = getattr(self, "handle_" + cherrypy.request.method, None) 
     if not method: 
     methods = [x.replace("handle_", "") 
      for x in dir(self) if x.startswith("handle_")] 
     cherrypy.response.headers["Allow"] = ",".join(methods) 
     raise cherrypy.HTTPError(405, "Method not implemented.") 
     return method(*vpath, **params); 

class FooResource(RESTResource): 
    def handle_GET(self, *vpath, **params): 
     retval = "Path Elements:<br/>" + '<br/>'.join(vpath) 
     query = ['%s=>%s' % (k,v) for k,v in params.items()] 
     retval += "<br/>Query String Elements:<br/>" + \ 
      '<br/>'.join(query) 
     return retval 

class Root(object): 
    foo = FooResource() 

    @cherrypy.expose 
    def index(self): 
     return "REST example." 

cherrypy.quickstart(Root()) 

您只需从RESTResource类派生和处理两者的RESTful动词,你的愿望(GET,PUT, POST,DELETE),同名方法的前缀为handle_。如果您不处理特定动词(如POST),则基类将为您提出405 Method Not Implemented错误。

路径项目在vpaths中传递,并且任何查询字符串都被传入params。使用上面的示例代码,如果您要请求/foo/bar?woo=hoovpath[0]将为bar,并且params将为{'woo': 'hoo'}

1

要回答你的第二个问题,你要定义和暴露默认的方法:使用此方法

class getOrders(Object): 
    def default(account, type): 
     ... 

    default.exposed = True 

,getOrders/X/Y将映射到default(account='x', type='y')。就像其他人说的那样,这不是很好,但它完成了工作。

就REST风格的应用程序而言,我敢肯定,默认页面处理程序将适用于这样的应用程序。

2

所以要变换/ getOrders? account = X & type = Y使用Cherrypy将其转换为/ orders/account /类型。

我会尝试在http://cherrypy.readthedocs.org/en/latest/tutorial/REST.html中使用的方法,如@Tomasz Blachowicz所述,并进行一些修改。

请记住,你可以处理类似/顺序/帐号/类型与

@cherrypy.expose 
def order(account=None, type=None): 
    print account, type 

class Root(object): 
    pass 

root = Root() 
root.orders = orders 


cherrypy.quickstart(root, '/') 

所以,如果你把在http://cherrypy.readthedocs.org/en/latest/tutorial/REST.html给出的例子,你可以修改它来处理这类网址。

class Orders(object): 
    exposed = True 
    def __init__(self): 
     pass 

    def GET(self, account=None, type=None): 
     #return the order list for this account type 
     return getOrders(account, type) 

    def PUT(self, account=None, type=None, orders=None): 
     #Set the orders associated with account or something 
     setOrders(account, type, orders) 


class Root(object): 
    pass 

root = Root() 
root.orders = Orders() 

conf = { 
    'global': { 
     'server.socket_host': '0.0.0.0', 
     'server.socket_port': 8000, 
    }, 
    '/': { 
     'request.dispatch': cherrypy.dispatch.MethodDispatcher(), 
    }, 
} 

cherrypy.quickstart(root, '/', conf) 

为什么你要设置使用put方法我不知道订单,但它确实给了怎么办PUT方法的另一个例子。你所要做的就是用PUT替换请求使用的方法,它将使用Orders的PUT()方法,并在Orders上使用常规GET,并使用GET()方法。由于POST()方法未定义,因此POST不能用于此示例。如果您尝试POST或DELETE,您将得到“405方法不允许”。

我喜欢这种方法,因为它很容易看到发生了什么,我相信它会回答你的问题。