Sanic: RESTful router

Created on 16 Jan 2017  路  7Comments  路  Source: sanic-org/sanic

Hi all,

there is a nice TODO on the list: A RESTful router. Since this would be very nice to have, I started to implement a RESTful router. The implementation is similar to a Rails Ressource. In general a Plan to do the following changes:

  • Create a Resource Base Class like (HTTPMethodView)
  • Decorators for custom mappings (Method, Url)
  • New sanic app method to add a resource

I would like to know if there is any implementation already and if you have any comments. :-)

enhancement nice to have

Most helpful comment

Doesn't the existing HTTPMethodView cover the typical use case for REST API construction? ie

class SimpleView(HTTPMethodView):

  def get(self, request):
      return json({})

  def post(self, request):
     return json({})

  def put(self, request):
     return json({})

  def patch(self, request):
      return json({})

  def delete(self, request):
      return json({})

app.add_route(SimpleView.as_view(), '/')

I'm wondering if your idea would better work as an extension (like Flask-Restful) instead of in the core?

All 7 comments

Doesn't the existing HTTPMethodView cover the typical use case for REST API construction? ie

class SimpleView(HTTPMethodView):

  def get(self, request):
      return json({})

  def post(self, request):
     return json({})

  def put(self, request):
     return json({})

  def patch(self, request):
      return json({})

  def delete(self, request):
      return json({})

app.add_route(SimpleView.as_view(), '/')

I'm wondering if your idea would better work as an extension (like Flask-Restful) instead of in the core?

Yes and no. Normally, there is one route without a parameter handling get (list) and post (create) and one route with a parameter handling get (view), put/patch (modify), delete (delete).

I just read the todo on the front page.^^ I don't mind, if there is no interest for such code in the core, please remove the todo. ;-)

My current code is nowhere near what flask-restful supports. It just allows simple nested resources with convenient function names and route generation. As I said, it is close to the rails resource implementation.

@go2sh is this sorta what you were looking for? https://github.com/channelcat/sanic/pull/311

Yes and no, the merging feature is nice. I'll publish my code (hopefully (tm)) this evening. Maybe, it's better to put it into some kind of extension, since I'am planning to support more than just a RessourceView class. Maybe you can have a look if there is something you want to see in the core.

I think we covered this with route overloading in 0.3.0 and 0.3.1. Will reopen if necessary.

Most of the time, when creating a Rest Resource, PUT, PATCH and DELETE methods requires a different routing path to include an id path parameter.

This is the API I would expect to create a Rest Resource responding to all HTTP methods

class Resource(HTTPMethodView):
  def get(self, request):
      return json({})

  def post(self, request):
     return json({})

  @app.route('<id>')
  def put(self, request, id):
     return json({})

  @app.route('<id>')
  def patch(self, request, id):
      return json({})

  @app.route('<id>')
  def delete(self, request, id):
      return json({})

app.add_route(Resource.as_view(), '/resource')

But it's not supported. It seems I have to split the view in two classes, one for GET/POST, and another one for PUT/PATCH/DELETE, but it's not really obvious for newcomers like me.

class Resource(HTTPMethodView):
  def get(self, request):
      return json({})

  def post(self, request):
     return json({})

class ResourceAlter(HTTPMethodView):
  def put(self, request, id):
     return json({})

  def patch(self, request, id):
      return json({})

  def delete(self, request, id):
      return json({})

app.add_route(Resource.as_view(), '/resource')
app.add_route(ResourceAlter.as_view(), '/resource/<id>')
api = Blueprint('api', url_prefix='/api', strict_slashes=True)

def register_api(view, url, pk='id', pk_type='int'):
    view_func = view.as_view()
    api.add_route(view_func, url, methods=['GET', 'POST'])
    api.add_route(view_func, f'{url}<{pk}:{pk_type}>', methods=['GET', 'PUT', 'DELETE'])

register_api(classView, '/topics/')
Was this page helpful?
0 / 5 - 0 ratings

Related issues

Souldat picture Souldat  路  3Comments

aiurlano picture aiurlano  路  4Comments

olalonde picture olalonde  路  3Comments

graingert picture graingert  路  3Comments

ZeeRoc picture ZeeRoc  路  3Comments