1.5.13. /db/_design/design-doc/_rewrite/path — Apache CouchDB® 3.2 Documentation

# 1.5.13. `/db/_design/design-doc/_rewrite/path`

Warning

Rewrites are deprecated in CouchDB 3.0, and will be removed in CouchDB 4.0.

`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.

    function(req2) {
      var path = req2.path.slice(4),
        isWrite = /^(put|post|delete)$/i.test(req2.method),
        isFinance = req2.userCtx.roles.indexOf("finance") > -1;
      if (path[0] == "finance" && isWrite && !isFinance) {
        // 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;
    }

## 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:

> 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 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