Letting Browsers use all of the RESTful Methods in Google App Engine
So there was much talk and whathave you about Google's new App Engine, and after viewing the tutorials and reading the documentation, I thought it was pretty rad too. Because I was using rack for some previous stuff, WSGI felt right at home (probably because rack was modeled after WSGI). There was one thing that bothered me however. When writing a class using their webapp framework there isn't any magic param name, like _method
, that I could use to mock requests methods like DELETE
and PUT
since the browser doesn't support those HTTP methods.
Well my friends, fear not. If you enjoy the sweet freedom of RESTful urls, I'm here to help. Since this is all built on top of WSGI, we can create a some new Middleware to sit before the application to resolve this little issue.
MockHTTPMethodMiddleware
1from google.appengine.ext import webapp
2
3class MockHTTPMethodMiddleware(object):
4 def __init__(self, app):
5 self.app = app
6
7 def __call__(self, environ, start_response):
8 method = webapp.Request(environ).get('_method')
9 if method:
10 environ['REQUEST_METHOD'] = method.upper()
11 return self.app(environ, start_response)
The code is pretty simple. So when this middleware is called, it processes the environ
into a Request
object. From there, I just inspect the params for a key called _method
. If that param exists, then it overwrites the REQUEST_METHOD
and bam...we have mocked the HTTP method of our choosing.
Putting that code to good use
Let's pretend that this is our class is something inane like this:
1from google.appengine.ext import webapp
2
3class MethodTest(webapp.RequestHandler):
4 def get(self):
5 self.response.headers["Content-Type"] = 'text/text'
6 self.response.out.write("Get")
7
8 def put(self):
9 self.response.headers["Content-Type"] = 'text/text'
10 self.response.out.write("Put")
So now when you are writing your main
method that creates the WSGI application, you would write it something like:
1import wsgiref.handlers
2
3def main():
4 app = webapp.WSGIApplication(
5 [('/', MethodTest)],
6 debug=True)
7 wsgiref.handlers.CGIHandler().run(MockHTTPMethodMiddleware(app))
8
9if __name__ == "__main__":
10 main()
Notice that in the run method arguments, MockHTTPMethodMiddleware
takes app
as a parameter, thus MockHTTPMethodMiddleware
will run before it runs app
.
Conclusion
While there wasn't support out of the box for mocking HTTP methods for browsers, with a little help from a WSGI Middleware class, it's not too hard to add that functionality in, nor is it hard to add anything else you would want to use.
Comments
comments powered by Disqus