Reputation: 573
I am building on Google App Engine + Python + webapp2. Part of building a modern web app requires a restful API. I know that I can do this with Flask
, however I want to explore the possibility of building a REST API on webapp2
.
On webapp2, requests are handled like this:
app = webapp2.WSGIApplication([
('/post/new', CreatePost),
('/post/([a-z0-9]+)', ViewPost),
('/post/([a-z0-9]+)/edit', EditPost),
('/post/([a-z0-9]+)/delete', DeletePost)
])
Note: ([a-z0-9]+)
is a regex that represents the post_id
The above request handlers do not adhere to a RESTful pattern since the request methods
are specified in the path (/delete, /edit, /new) rather than in the request headers.
Is the solution to create a single handler class that receives all request types? For example:
class PostHandler(webapp2.RequestHandler):
def get(self):
# handle GET requests
def post(self):
# handle POST requests
def put(self):
# handle PUT requests
def delete(self):
# handle DELETE requests
app = webapp2.WSGIApplication([
('/post/?', PostHandler)
])
In this case, all /post
paths are handled by PostHandler. The post_id
is no longer used in this pattern since it would be submitted in the request body instead.
Is this the correct approach to building a REST API with webapp2?
Upvotes: 1
Views: 323
Reputation: 26652
One should extend webapp2.RequestHandler
and use the extension as the new base class for a RESTfulHandler
and then maybe also for your specific purpose extend the RESTfulHandler
to a RESTfulPostHandler
. This way we could also deal with new ways or work such as jwt (JSON web token) in the header, authorization and other properties that you wish to handle in the header.
BTW, "post" might not be the best name for your item/object since it could easily get mixed up with the http verb "post". If I were you, I would rename it into "item" or similar, and use a RESTfulItemHandler
which extends the webapp2 request handler. There are many things you would like to share between your handler and like that it is convenient to share the functionality in a base-class.
Upvotes: 0
Reputation: 5276
You are on the right path, but you should continue to handle post_id
in the url and do it like this:
class PostHandler(webapp2.RequestHandler):
def get(self, post_id=None):
if post_id:
# handle Fetching a single post object
else:
# handle Queries
def post(self, post_id=None):
if post_id:
self.abort(405)
# handle creating a single post object
def put(self, post_id=None):
if post_id:
# handle updating a single post object
else:
self.abort(405)
def delete(self, post_id=None):
if post_id:
# handle deleting a single post object
else:
self.abort(405)
app = webapp2.WSGIApplication([
('/post/<post_id>/', PostHandler),
('/post/', PostHandler),
])
Furthermore putting the HTTP verb within the request payload like voscausa
suggested is not inline with RESTful API design.
Upvotes: 1