couchdb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jason Davies <>
Subject Rewriting URLs
Date Sat, 04 Jul 2009 21:34:27 GMT
Hi all,

I've mostly completed work on a patch for a _rewrite handler.  This  
was one of the main missing pieces for me when trying to provide  
pretty/clean URLs when using CouchDB to deploy pure CouchApps behind a  
reverse proxy (Nginx).  My approach up until now has been to use  
Nginx's mod_rewrite to rewrite URLs using regular expressions.   
However, this is not workable for those of us who want to replicate  
CouchApps in a portable manner.

The basic idea is you add a "rewrites": [...] member to your design  
doc.  This will allow rewriting of any URLs with the prefix mydb/ 
_design/app/_rewrite.  The "rewrites" member is a list of rewrite  
rules of the form {match: ["foo/bar/<var>"], rewrite:["_view/myview",  
{startkey: ["<var>"], endkey: ["<var>", {}]}]

This is very similar to WebMachine's routing syntax, which would be  
something like ["foo", "bar", var] for the match part.  Notice how  
"<var>" is used to denote an atom.  Atoms in the target path and in  
the target query parameters are replaced with any tokens they matched  
in the source rule.  There is a special atom '*' that can be used (as  
in WebMachine) to match any number of path elements (normally atoms  
match a single path element).

The branch is here:

And a patch here if you don't use git:

And a paste of part of the test case if you are too lazy to click on  
those links:

     rewrites: [{
       match: ["any_view/<view>/<key>"],
       rewrite: ["_design/rewrite_test/_view/<view>", {key: "<key>"}]
       match: ["any_doc/<doc_id>/<*>"],
       rewrite: ["<doc_id>/<*>"]
       match: ["design_doc/<name>/<*>"],
       rewrite: ["_design/<name>/<*>"]

I still need to add a few more tests and think about perhaps allowing  
relative targets so that you can have a target of ../../blah or even / 
_uuids, and the possibility of special atoms e.g. <list>/mylist/myview  
to map to lists/views/shows/docs.

Any thoughts much appreciated,
Jason Davies

On 8 May 2009, at 01:15, Jason Davies wrote:

> On 7 May 2009, at 18:50, Jason Davies wrote:
>> On 7 May 2009, at 18:33, Justin Sheehy wrote:
>>> I've now changed the dispatcher such that it should be useful  
>>> outside
>>> of webmachine without affecting internal use.
> [snip]
>> This looks great, thanks very much!  I'll let you know how I get on.
> Okay, here's a first stab at this:
> The basic idea is you add "rewrites": [...] member to the design  
> doc.  This is a list of rewrite rules of the form: {"match": [...],  
> "rewrite": [...]}.  The "match" member is a list of path tokens to  
> be matched.  The "rewrite" member specifies the target path, also as  
> a list of path tokens.
> The match tokens can be either "foo" (specific match of "foo"),  
> ":foo" (any token, can be captured in the target path using ":foo",  
> equivalent to Erlang atom in WebMachine), or ":*" (only allowed at  
> the end of a list, matches any number of tokens, can be captured in  
> the target path using ":*", equivalent to Erlang atom '*' in  
> WebMachine).
> The target path is analogous to the match path, just that "atoms"  
> specify parts of the match path to be captured.
> Is this moving in the right direction?
> It seems this can't cope with things like rewriting /blog/2009/05/08/ 
> foo/ -> /db/blog%2F2009%2F05%2F08%2Ffoo though, or any other kind of  
> slightly more flexible regex-style rewriting problems.  Any thoughts  
> on this?
> Thanks,
> --
> Jason Davies

View raw message