Skip to main content

Proxy Rewrite plugin

The Proxy Rewrite plugin (technical name proxy-rewrite, Transformation group) rewrites request information before the API Gateway forwards it to the backend: the Host header, the path (URI), the HTTP method, or adding / changing / removing headers.

note

Proxy Rewrite is not a security plugin and never blocks requests. It only transforms valid requests, after they have passed other steps such as authentication and rate limiting.

Use cases​

The Proxy Rewrite plugin is suited to cases where the URI, host, method, or headers that clients send to the API Gateway differ from what the backend requires.

Typical cases:

  • The API Gateway publishes the path /v1/users, but the backend only accepts /internal/users: use uri or regex_uri to rewrite the path.
  • The backend requires an internal Host header that differs from the public domain clients call: use host.
  • A legacy backend accepts only one fixed method, for example POST: use method to send every request with that method.
  • Pass the authenticated Consumer name to the backend in a custom header, and remove the header that carries the original API key: combine headers.set with headers.remove.

Create a Proxy Rewrite plugin​

To create a Proxy Rewrite plugin, follow these steps:

  1. In the left menu, select API Gateway → Plugin, select the API Gateway in the top-right corner, click New plugin, then select Proxy Rewrite in the Add plugin popup. You can also add it from the Plugins tab of a Route / Service, see Add a plugin.

  2. In the Basic Information section, enter the Display Name. See Basic Information.

  3. Select the Configuration section. The form shows all 8 attributes, but all of them are empty. The grey text in the fields (iresty.com, /get, ^/rewrite-regex/(.*), /$1) is only an input hint, so the initial JSON is {}. The plugin has no required attributes and no Quick Start Templates: each attribute you fill in appears in the JSON.

Configuration section of the Proxy Rewrite plugin with empty fields

AttributeRequiredDescription
hostNNew Host header sent to the backend, replacing the original Host header of the client. Must be a valid domain name.
methodNChange the HTTP method of the request before forwarding it to the backend. Keep Keep original (default) to keep the original method.
uriNNew fixed path sent to the backend, supporting NGINX variables such as $arg_name. Must start with /. When both uri and regex_uri are set, uri takes priority.
regex_uriNA [pattern, replacement] pair that rewrites the path with a regex, used when the new path is derived from the original path. If pattern matches, the request is forwarded with replacement. Otherwise the original path is kept. $1, $2, and so on refer to capture groups. Click + Add to add a pair. The number of filled lines must be even.
use_real_request_uri_unsafeNUse the raw URI of the client and skip URI normalization. Unsafe, so turn it on only if you fully understand the security risk.
headers.addNAdd headers to the request. Existing headers with the same name are kept, not overwritten.
headers.setNOverwrite header values, or add the header if it does not exist. To change Host, use the host attribute instead of setting the Host header here.
headers.removeNRemove headers from the request before forwarding it to the backend. Only the header name is needed.

When all 3 header groups are set, they are processed in the order add → remove → set.

note

In the JSON, regex_uri is a flat array whose items come in [pattern, replacement] pairs. The 3 header groups sit in a headers object: add and set are objects like {"header-name": "value"}, and remove is an array of header names.

  1. Select the Scope section, choose Global or Scoped, then assign the Routes / Services. See Scope.

  2. Click Create. The message Plugin created successfully appears and the plugin appears in the list with the Applied to column matching the selected scope.

Sample configurations​

The 4 configurations below match the 4 cases in Use cases.

Change only the Host header and keep the path the client called:

{
"host": "backend.internal"
}

Strip a path prefix before reaching the backend: the client calls /v1/users/42, and the backend receives /users/42:

{
"regex_uri": [
"^/v1/(.*)",
"/$1"
]
}

Change the path to a fixed value and force the method (a legacy backend that accepts only POST). When both uri and regex_uri are set, uri takes priority, so usually use only one of them:

{
"uri": "/internal/users",
"method": "POST"
}

Pass the authenticated Consumer name to the backend in a custom header, and remove the header that carries the original API key:

{
"headers": {
"set": {
"X-Consumer-Name": "$consumer_name",
"X-Forwarded-Client-IP": "$remote_addr"
},
"remove": [
"X-API-Key"
]
}
}
note

Values starting with $ are NGINX variables, replaced with real values when the request passes through the API Gateway. $consumer_name has a value only when the Route / Service has an authentication plugin (such as JWT Auth) running first. Otherwise the header is empty.

Common issues​

The form checks the values and shows errors as you type:

ErrorCauseSolution
host shows an errorThe value is not a valid domain nameEnter a valid domain name, for example backend.internal.
uri shows an errorThe value does not start with /Add / at the start, for example /internal/users.
regex_uri shows an errorThe number of filled lines is odd, so a pattern has no replacementFill in each pattern / replacement pair.
A header name shows an errorThe header name contains :Remove : from the header name.

Next steps​

Last updated on