POST implementation. This has to add a new feed to the user's list of feeds:
def post(http): """Update a user's list of feeds with a new feed.""" username = http.user form = util.FieldStorage(http) suggested_feed = form["suggested_feed"] def add_feeds(): try: dbcon = PgSQL.connect(http.get_options()["DBURL-" + http.hostname]) curs = dbcon.cursor() curs.execute("select add_feed('%s', '%s')" % (username, suggested_feed)) curs.execute("select id, url from get_feeds('%s')" % (username)) result = curs.fetchone() while result != None: yield result result = curs.fetchone() dbcon.close() except: pass return http.content_type = "text/html" http.status = HTTP_CREATED xmlout(add_feeds, http) return apache.OK
Here's what the HTTP spec says about
POSTmethod is used to request that the web server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI.
The spec goes on to say that one specific reason for
POST is to allow append operations on databases. That is exactly what this part of the feeds application does; it appends a new feed to a user's list.
I am cheating a bit here. The return from the
POST is not exactly REST compliant. A 201 response indicates that the server has created a new resource, but this response is supposed to include a resource indicating a reference to the new resource (including a
Location header, as in a redirect response).
However, the example simply returns the same list of feeds as returned from the
GET method. In my defense, this isn't too big a heresy, and it simplifies these examples a bit. Again, it's possible to support XML output by adding content negotiation.
The last method to implement is the
DELETE method. This must remove a feed specified by its ID from the user's feed list:
def delete(http): """Remove a feed from the user's list""" username = http.user todelete_match = re.match("/([0-9]+)", http.path_info) todelete = todelete_match.groups() try: dbcon = PgSQL.connect(http.get_options()["DBURL-" + http.hostname]) curs = dbcon.cursor() curs.execute("select delete_user_feed('%s', %d)" % (username, int(todelete))) except Exception, e: # Possibly just from the proc, whatever - it failed. http.status = apache.HTTP_NOT_FOUND dbcon.close() else: dbcon.commit() dbcon.close() http.status = apache.HTTP_OK return apache.OK
This is pretty obvious. It simply makes another database call to remove the specified feed.