Deron Meranda
deron.meranda at gmail.com
Fri Jan 4 04:32:14 EST 2008
On Jan 3, 2008 10:56 PM, Rajarshi Guha <rguha at indiana.edu> wrote: > Hi, I'm trying to wrap my head around a REST style interface using > mod_python. REST and mod_python are for the most part unrelated. But you can certainly use mod_python in a REST style (meaning that mod_python doesn't get in your way of doing REST). > My understanding of REST so far is that URI's should not > specify specific actions (as in /service.py?action=delete). Correct. The main point of REST is that your URLs identify resources (think nouns). You'll typically have lots and lots of URLs; a different URL for each possible different thing or item. An opposite style is SOA (which is basically a more complex evolution of CGI), in which the URLs name services or functions instead (think verbs). SOAs usually have very few URLs, but perhaps with lots and lots of "arguments". REST exposes things but hides the actors. SOA exposes the actors but hides the things. With REST, what you want to do to the resource (the verb) is specified by the HTTP method which is part of the request protocol... it is never encoded into the URL. The methods can be things like GET, PUT, DELETE, etc. The POST method is generally frowned upon in a REST usage, but it can be valid in certain cases. The same URL is used regardless of method as long as whatever you're doing is being done to the same resource. The whole REST style can be more involved, but it generally is much closer to the original web/HTTP architecture. Things like ETags and content negotiation can be big deals in REST; while they are blissfully ignored in most SOA approaches. Perhaps one of the most widely used non-trivial REST applications on Apache is Subversion (via mod_dav_svn since it's written in C and not python). > Thus I'd like to be able to handle a URL like > http://www.somehost.com/service.py/descriptor/CCCC > where CCCC is an argument to the service. No, don't think argument to a *service*....that's an SOA mindset. Also you most certainly don't want something like "service.py" being visible in the URL. A better URL would just be http://www.somehost.com/descriptor/CCCC Think of /descriptor/CCCC instead as being a unique *name* for some resource or object. Remember, with REST there is no action or verb implied by the URL; everything is just a name for things/nouns. > Is something like this possible in mod_python? Yes, REST is very doable. Since mod_python is so low-level (as contrasted with many web "frameworks"), it doesn't force you to use any one particular style or architecture for your applications. > If anybody could point > me to some examples of REST interfaces built using mod_python, it > would be much appreciated. If you're just trying to understand REST concepts, start with http://en.wikipedia.org/wiki/Representational_State_Transfer but do be aware that more and more misinformation about REST is starting to show up as the marketing types are grabbing on the the term as a buzzword. Sometimes SOA-style architectures are being described as REST even when they are technically not so. (the latest such mislabeled example being Amazon's SimpleDB) A very simple "hello world" like REST-style handler could be structured similar to the following (note this is not complete code and is not tested): The important thing to notice is that when doing REST you are usually going to be doing some sort of switch on the req.method value. def handler( req ): # Extract the resource name (the CCCC portion of the URL): uripath = [p for p in req.uri.split('/') if p] if len(uripath) != 2 or uripath[0] != 'descriptor': raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND resource_name = uripath[-1] # Now figure out what we want to do to the resource if req.method == 'GET': try: content = resource_database[resource_name] except KeyError: raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND req.content_type = 'application/octet-stream' req.write( content ) elif req.method == 'PUT': content = req.read() resource_database[resource_name] = content elif req.method == 'DELETE': del resource_database[resource_name] else: raise apache.SERVER_RETURN, apache.HTTP_METHOD_NOT_ALLOWED return apache.OK -- Deron Meranda
|