What's the best approach of creating a RESTful web api in CherryPy? I've been looking around for a few days now and nothing seems great. For Django it seems that are lots of tools to do this, but not for CherryPy or I am not aware of them.
Later edit: How should I use Cherrypy to transform a request like /getOrders?account=X&type=Y into something like /orders/account/type ?
I don't know if it's the "best" way, but here's how I do it:
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())
You simply derive from the RESTResource
class and handle whichever RESTful verbs you desire (GET, PUT, POST, DELETE) with a method of the same name prefixed with handle_
. If you do not handle a particular verb (such as POST) the base class will raise a 405 Method Not Implemented
error for you.
The path items are passed in vpaths
and any query strings are passed in in params
. Using the above sample code, if you were to request /foo/bar?woo=hoo
, vpath[0]
would be bar
, and params
would be {'woo': 'hoo'}
.