1.5.13. /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 by the rewrites field of the design document. The rewrites field can either be a string containing the a rewrite function or an array of rule definitions.

1.5.13.1. Using a stringified function for rewrites

New in version 2.0: When the rewrites field is a stringified function, the query server is used to pre-process and route requests.

The function takes a Request2 object.

The return value of the function will cause the server to rewrite the request to a new location or immediately return a response.

To rewrite the request, return an object containing the following properties:

  • path (string): Rewritten path.
  • query (array): Rewritten query. If omitted, the original query keys are used.
  • headers (object): Rewritten headers. If omitted, the original request headers are used.
  • method (string): HTTP method of rewritten request ("GET", "POST", etc). If omitted, the original request method is used.
  • body (string): Body for "POST"/"PUT" requests. If omitted, the original request body is used.

To immediately respond to the request, return an object containing the following properties:

  • code (number): Returned HTTP status code (200, 404, etc).
  • body (string): Body of the response to user.

Example A. Restricting access.

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

Example B. Different replies for JSON and HTML requests.

  1. function(req2) {
  2. var path = req2.path.slice(4),
  3. h = headers,
  4. wantsJson = (h.Accept || "").indexOf("application/json") > -1,
  5. reply = {};
  6. if (!wantsJson) {
  7. // Here we should prepare reply object
  8. // for plain HTML pages
  9. } else {
  10. // Pass through JSON requests
  11. reply.path = "../../../"+path.join("/");
  12. }
  13. return reply;
  14. }

1.5.13.2. Using an array of rules for rewrites

When the rewrites field is an array of rule objects, the server will rewrite the request based on the first matching rule in the array.

Each rule in the array is an object with the following fields:

  • method (string): HTTP request method to bind the request method to the rule. If omitted, uses "*", which matches all methods.
  • from (string): The pattern used to compare against the URL and define dynamic variables.
  • to (string): The path to rewrite the URL to. It can contain variables depending on binding variables discovered during pattern matching and query args (URL args and from the query member).
  • query (object): Query args passed to the rewritten URL. They may contain dynamic variables.

The to and from paths may contains string patterns with leading : or * characters to define dynamic variables in the match.

The first rule in the rewrites array that matches the incoming request is used to define the rewrite. To match the incoming request, the rule’s method must match the request’s HTTP method and the rule’s from must match the request’s path using the following pattern matching logic.

  • The from pattern and URL are first split on / to get a list of tokens. For example, if from field is /somepath/:var/* and the URL is /somepath/a/b/c, the tokens are somepath, :var, and * for the from pattern and somepath, a, b, and c for the URL.
  • Each token starting with : in the pattern will match the corresponding token in the URL and define a new dynamic variable whose name is the remaining string after the : and value is the token from the URL. In this example, the :var token will match b and set var = a.
  • The star token * in the pattern will match any number of tokens in the URL and must be the last token in the pattern. It will define a dynamic variable with the remaining tokens. In this example, the * token will match the b and c tokens and set * = b/c.
  • The remaining tokens must match exactly for the pattern to be considered a match. In this example, somepath in the pattern matches somepath in the URL and all tokens in the URL have matched, causing this rule to be a match.

Once a rule is found, the request URL is rewritten using the to and query fields. Dynamic variables are substituted into the : and * variables in these fields to produce the final URL.

If no rule matches, a 404 Not Found response is returned.

Examples:

RuleURLRewrite toTokens
    {“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=vk=v
    {“from”: “/a/b”,
    “to”: “/some/:var”}
/a/b/some/b?var=bvar=b
    {“from”: “/a/:foo/”,
    “to”: “/some/:foo/”}
/a/b/c/some/b/c?foo=bfoo=b
    {“from”: “/a/:foo”,
    “to”: “/some”, “query”: { “k”: “:foo” }}
/a/b/some/?k=b&foo=bfoo=b
    {“from”: “/a”,
    “to”: “/some/:foo”}
/a?foo=b/some/?b&foo=bfoo=b

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

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