openplans / openblock

OpenBlock is a web application and RESTful service that allows users to browse and search their local area for "hyper-local news
61 stars 26 forks source link

URLs parsed by ebpub.db.views.schema_filter aren't so great #113

Closed slinkp closed 11 years ago

slinkp commented 11 years ago

The schema_filter view parses URL sub-paths of the form:

 /restaurant-inspections/by-date/2010-12-29,2010-12-29/by-result/pass-wminor-violations/by-violation/12/by-restaurant-name/Foo/locations/neighborhoods/hyde-park/

Everything after restaurant-inspections/ is parsed by the schema_filter view into parameters. Two problems with the URL format:

1) It's misleading. Slashes create an impression of hierarchy where none exists. We aren't drilling into a hierarchy - we're filtering, and the order of filters does not matter to the end result. It's possible to re-order the path segments into a number of functionally equivalent URLs.

2) It's a little fragile to parse, since each path segment like "by-foo" must be followed by exactly the right number of path segments, which varies depending on what "foo" is.

Both of these issues could be solved in a number of ways.

1) Treating it as a search and passing the parameters via query string. This would work, although requests with query strings aren't always trivially cacheable by caching proxies, and you can't do reverse URL lookup since Django's URL lookup engine ignores query strings (relevant to #69). For example, something like:

    /restaurant-inspections/?start-date=2010-12-29&end_date=2010-12-29&by-result=pass-wminor-violations&by-violation=12&by-restaurant-name=Foo&location-type=neighborhoods&location=hyde-park

2) Put the parameters into an encoded form into a single path segment, a la Matrix URLs (http://www.w3.org/DesignIssues/MatrixURIs.html) I somewhat favor this option, as it offers good cacheability and it's at least theoretically possible to do reverse URL lookups. Example equivalent to the above:

    /restaurant-inspections/by-date=2010-12-29,2010-12-29;by-result=pass-wminor-violations;by-violation=12;by-restaurant-name=Foo;locations=neighborhoods,hyde-park/

Also consider normalizing the order of filters: we get better cacheability by redirecting to the normalized form of the URL, and we can choose a normalized form that puts the least expensive database operations first.

(See also #112 and #69)

slinkp commented 11 years ago

Closed in changeset 64ed509c28b0d102d29a8facebf1360938277714 using the matrix URI approach. But I'm considering switching to query strings: it seems to be preferred on the ebcode list, and we can't just use urlresolvers.reverse() anyway, I had to create a reverse_filters() function anyway. Things should be reasonably encapsulated now so hopefully switching to query strings wouldn't be nearly so much effort.

slinkp commented 11 years ago

Ticket imported from Trac: http://developer.openblockproject.org/ticket/113 Reported by: slinkp