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: http://github.com/jasondavies/couchdb/tree/rewrite
And a patch here if you don't use git: http://gist.github.com/140738
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
www.jasondavies.com
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:
http://github.com/jasondavies/couchdb/commit/f6cb4012269e5331c5bf95077a00a4a09c9ea029
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
www.jasondavies.com