11.5.11. /db/_design/design-doc/_rewrite/path

ANY /{db}/_design/{ddoc}/_rewrite/{path}

Rewrites the specified path by rules defined in the specified design document. The rewrite rules are defined in array or string field of the design document called rewrites.

11.5.11.1. Rewrite section a is stringified function

‘Rewrite using JS’ feature was introduced in CouchDB 1.7. If the rewrites field is a stringified function, query server is used to pre-process and route a request.

The function receives truncated version of req object as a single argument and must return object, containing new information about request.

Returned object should include properties as:

  • path (string): Rewritten path, mandatory if no code provided
  • query (array): Rewritten query, if omitted original query keys are used
  • headers (object): Rewritten headers. If omitted, original request headers are used
  • method (string): Method of rewritten request. If omitted, original request method is used
  • code (number): Returned code. If provided, request is not rewritten and user immediately receives response with the code
  • body (string): Body for POST/PUT requests, or for returning to user if code field provided. If POST/PUT request is being rewritten and no body returned by rewrite function, original request body is used

Example A. Restricting access.

function(req2) {
  var path = req2.path.slice(4),
    isWrite = /^(put|post|delete)$/i.test(req2.method),
    isFin = req2.userCtx.roles.indexOf("finance")>-1;
  if (path[0] == "finance" && isWrite && !isFin) {
    // Deny writes to  DB "finance" for users
    // having no "finance" role
    return {
      code: 403,
      body:JSON.stringify({
        error:"forbidden".
        reason:"You are not allowed to modify docs in this DB"
      })
    }
  }
  // Pass through all other requests
  return {path:"../../../"+path.join("/")}
}

Example B. Different replies for JSON and HTML requests.

  function(req2) {
    var path = req2.path.slice(4),
      h = headers,
      wantsJson = (h.Accept||"").indexOf("application/json")>-1,
      reply = {};
    if (!wantsJson) {
      // Here we should prepare reply object
      // for plain HTML pages
    } else {
      // Pass through JSON requests
      reply.path = "../../../"+path.join("/");
    }
    return reply;
  }

The req2 object rewrites is called with is a slightly truncated version
of req object, provided for list and update functions. Fields *info*,
*uuid*, *id* and *form* are removed to speed up request processing.
All other fields of the req object are in place.

11.5.11.2. Rewrite section is an array

Each rule is an object with next structure:

  • from (string): The path rule used to bind current URI to the rule. It uses pattern matching for that.
  • to (string): Rule to rewrite a URL. It can contain variables depending on binding variables discovered during pattern matching and query args (URL args and from the query member)
  • method (string): HTTP request method to bind the request method to the rule. Default is "*"
  • query (object): Query args you want to define they can contain dynamic variable by binding the key

The to``and ``from paths may contains string patterns with leading : or * characters.

For example: /somepath/:var/*

  • This path is converted in Erlang list by splitting /
  • Each var are converted in atom
  • "" are converted to '' atom
  • The pattern matching is done by splitting / in request URL in a list of token
  • A string pattern will match equal token
  • The star atom ('*' in single quotes) will match any number of tokens, but may only be present as the last pathterm in a pathspec
  • If all tokens are matched and all pathterms are used, then the pathspec matches

The pattern matching is done by first matching the HTTP request method to a rule. method is equal to "*" by default, and will match any HTTP method. It will then try to match the path to one rule. If no rule matches, then a 404 Not Found response returned.

Once a rule is found we rewrite the request URL using the to and query fields. The identified token are matched to the rule and will replace var. If '*' is found in the rule it will contain the remaining part if it exists.

Examples:

Rule URL Rewrite to Tokens
{“from”: “/a”,
“to”: “/some”}
/a /some  
{“from”: “/a/*”,
“to”: “/some/*}
/a/b/c /some/b/c  
{“from”: “/a/b”,
“to”: “/some”}
/a/b?k=v /some?k=v k=v
{“from”: “/a/b”,
“to”: “/some/:var”}
/a/b /some/b?var=b var=b
{“from”: “/a/:foo/”, “to”: “/some/:foo/”} /a/b/c /some/b/c?foo=b foo=b
{“from”: “/a/:foo”,
“to”: “/some”, “query”: { “k”: “:foo” }}
/a/b /some/?k=b&foo=b foo=b
{“from”: “/a”,
“to”: “/some/:foo”}
/a?foo=b /some/?b&foo=b foo=b

Request method, header, query parameters, request payload and response body are depended on endpoint to which URL will be rewritten.

param db:Database name
param ddoc:Design document name
param path:URL path to rewrite