10.5.11. /db/_design/design-doc/_rewrite/path — Apache CouchDB 2.1 Documentation

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

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

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