From 39b8b920c8018dc4d124cba72794da1dcc925cce Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 31 Jul 2008 07:47:43 +0000 Subject: More balance between URL dispatch and traversal. --- docs/narr/urlmapping.rst | 99 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 docs/narr/urlmapping.rst (limited to 'docs/narr/urlmapping.rst') diff --git a/docs/narr/urlmapping.rst b/docs/narr/urlmapping.rst new file mode 100644 index 000000000..3c74d04d9 --- /dev/null +++ b/docs/narr/urlmapping.rst @@ -0,0 +1,99 @@ +.. _url_mapping_chapter: + +Mapping URLs to Code +==================== + +Many popular web frameworks today use :term:`URL dispatch` to +associate a particular URL with a bit of code (known somewhat +ambiguously as a "controller" or :term:`view` depending upon the +particular vocabulary religion to which you subscribe). These systems +allow the developer to create "urlconfs" or "routes" to +controller/view Python code using pattern matching against URL +components. Examples: `Django's URL dispatcher +`_ and the +:term:`Routes` URL mapping system. + +:mod:`repoze.bfg` supports :term:`URL dispatch` via :term:`Routes`. +:term:`URL dispatch` is convenient and straightforward. When you +limit your application to using URL dispatch, you know every URL that +your application might generate or respond to, and all the URL +matching elements are listed in a single place. + +Like :term:`Zope`, :mod:`repoze.bfg`, in contrast to URL dispatch, can +also map URLs to code slightly differently, by using using object +graph :term:`traversal`. Graph-traversal based dispatching is useful +if you like your URLs to represent an arbitrary hierarchy of +potentially heterogeneous items, or if you need to attach +"instance-level" security (akin to "row-level" security in relational +parlance) declarations to :term:`model` instances. + +Differences Between Traversal and URL Dispatch +---------------------------------------------- + +:term:`URL dispatch` can easily handle URLs such as +``http://example.com/members/Chris``, where it's assumed that each +item "below" ``members`` in the URL represents a member in the system. +You just match everything "below" ``members`` to a particular view. + +For example, you might configure a :term:`Routes` URL map to match +against the following URL patterns:: + + archives/:year/:month/:day + members/:membername + +In this configuration, there are exactly two types of URLs that will +match views in your application: ones that start with ``/archives`` +and have subsequent path elements that represent a year, month, and +day. And ones that start with ``/members`` which are followed by a +path segment containing a member's name. This is very simple. + +:term:`URL dispatch` is not very good, however, at inferring the +difference between sets of URLs such as:: + + http://example.com/members/Chris/document + http://example.com/members/Chris/stuff/page + +...wherein you'd like the ``document`` in the first URL to represent a +PDF document, and ``/stuff/page`` in the second to represent an +*OpenOffice* document in a "stuff" folder. It takes more pattern +matching assertions to be able to make URLs like these work in +URL-dispatch based systems, and some assertions just aren't possible. +For example, URL-dispatch based systems don't deal very well with URLs +that represent arbitrary-depth hierarchies. + +Graph :term:`traversal` works well if you need to divine meaning out +of these types of "ambiguous" URLs and URLs that represent +arbitrary-depth hierarchies. Each URL segment represents a single +traversal through an edge of the graph. So a URL like +``http://example.com/a/b/c`` can be thought of as a graph traversal on +the ``example.com`` site through the edges ``a``, ``b``, and ``c``. + +If you're willing to treat your application models as a graph that can +be traversed, it also becomes easy to provide "row-level security" (in +common relational parlance): you just attach a security declaration to +each instance in the graph. This is not as easy in frameworks that +use URL-based dispatch. + +Graph traversal is materially more complex than URL-based dispatch, +however, if only because it requires the construction and maintenance +of a graph, and it requires the developer to think about mapping URLs +to code in terms of traversing the graph. (How's *that* for +self-referential! ;-) ) + +In essence, the choice to use graph traversal vs. URL dispatch is +largely religious in some sense. Graph traversal dispatch probably +just doesn't make any sense when you possess completely "square" data +stored in a relational database. However, when you have a +hierarchical data store, it can provide advantages over using +URL-based dispatch. + +:mod:`repoze.bfg` provides support for both approaches. You can use +either as you see fit. + +.. note:: + + Most existng :mod:`repoze.bfg` applications use :term:`traversal` to + map URLs to code. This is mostly due to the :term:`Zope` heritage + of :mod:`repoze.bfg` and because it aids applications that require + highly granular declarative security assertions. + -- cgit v1.2.3