URLs dispatching, Routes and Views

Cool URIs don't change
- w3.org

General Recommendations That I usualy follow:

  • make explicit bindings URL to Route and Route to View
  • name route with app prefix - 'project.app.route'
  • URL is for humans, make it readable
  • URL must mirror current context and/or action
  • All states and object of app should be accessible by URL
  • Always use pagination!
  • Add version info your public API, '/v3/' versus '?...&v=3'
  • Use slugs instead of real ID's
  • Traversal is great, use it! - '/tickets/12/messages/5'
  • For JSON use stateless approach and send additional info

Flask

URL assigns to view, view is a function, route is a function name. Docs doesn't propagate to have concepts of separate url-route-view, but it is still possible to have explicit url-route-view binding and so called 'pluggable views' which doesn't require to have instantiated app. Flask injects variables into view __locals__ so you have no idea what is going on...

@app.route('/add/', methods=['POST'], endpoint='view_name_by_default')
def myview(name):
   request...  # request variable is magically injected here
   db...       # same goes to DB
   return Responce(...)

Django

There is a register of URLs, URL is RegExp based, route name may be specified. View is a class or function. Class view implementation is a bit simple on the low-level, get, post, put, ... - who needs classes like that, it distracts from buissines logic!!! Classes are non-pythonic - you would be quite disappointed if try to use init method, but there is 'dispatch' and 'view' methods may work for initial workaround.

def my_view(request):
    # ...
    # Return a "created" (201) response code.
    return HttpResponse(status=201)

# in urls py
from django.conf.urls import url

urlpatterns = [
   url(r'^articles/([0-9]{4})/$', myview),
   url(r'^articles/([0-9]{4})/$', 
       views.year_archive, 
       name='news-year-archive'),
]

Pyramid

URL assigns to route and route to view, that is explicit. View is a function or class. Class views allows decoupling functionality between class methods that encapsulates all view logic quite well.

from pyramid.view import view_config, view_defaults
from pyramid.response import Response

@view_defaults(route_name='dynamic_ad')
class RESTView(object):

    def __init__(self, request):
        self.request = request

    # route predicate
    @view_config(match_param="provider=nba")
    def nba(self):
        return Response(...)

    @view_config(match_param="provider=nhl")
    def nhl(self):
        return Response(...)

    @view_config(match_param="provider=nhl", method="post")
    def post(self):
        return Response('post')
 
# ...
config = Configurator()
config.add_route('dynamic_ad', 'dynamic_ad_url/{provider}/')

 

Prev Post Next Post