puoygae
puoygae

Reputation: 573

webapp2 + RESTful API

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

Answers (2)

Niklas Rosencrantz
Niklas Rosencrantz

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

Alex
Alex

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

Related Questions