Transform the response sent by the upstream server on the fly on Kong, before returning the response to the client.

Note on transforming bodies: Be aware of the performamce of transformations on the response body. In order to parse and modify a JSON body, the plugin needs to retain it in memory, which might cause pressure on the worker's Lua VM when dealing with large bodies (several MBs). Because of Nginx's internals, the `Content-Length` header will not be set when transforming a response body.

Terminology

  • plugin: a plugin executing actions inside Kong before or after a request has been proxied to the upstream API.
  • API: (deprecated) the Kong entity representing your upstream service placed behind Kong, for which Kong proxies requests to.
  • Service: the Kong entity representing an external upstream API or microservice.
  • Route: the Kong entity representing a way to map downstream requests to upstream services.
  • Consumer: the Kong entity representing a developer or machine using the API. When using Kong, a Consumer only communicates with Kong which proxies every call to the said upstream API.
  • Credential: a unique string associated with a Consumer, also referred to as an API key.
  • upstream service: this refers to your own API/service sitting behind Kong, to which client requests are forwarded.

Configuration

Enabling the plugin for a Service

Configure on top of a Service by executing the following request on your Kong server:

$ curl -X POST http://kong:8001/services/{service}/plugins \
    --data "name=response-transformer"  \
    --data "config.remove.headers=x-toremove, x-another-one" \
    --data "config.remove.json=json-key-toremove, another-json-key" \
    --data "config.add.headers=x-new-header:value,x-another-header:something" \
    --data "config.add.json=new-json-key:some_value, another-json-key:some_value" \
    --data "config.append.headers=x-existing-header:some_value, x-another-header:some_value"
  • service: the id or name of the Service that this plugin configuration will target.

Enabling the plugin for a Route

Configure on top of a Route with:

$ curl -X POST http://kong:8001/routes/{route_id}/plugins \
    --data "name=response-transformer"  \
    --data "config.remove.headers=x-toremove, x-another-one" \
    --data "config.remove.json=json-key-toremove, another-json-key" \
    --data "config.add.headers=x-new-header:value,x-another-header:something" \
    --data "config.add.json=new-json-key:some_value, another-json-key:some_value" \
    --data "config.append.headers=x-existing-header:some_value, x-another-header:some_value"
  • route_id: the id of the Route that this plugin configuration will target.

Enabling the plugin for an API

If you are using the deprecated API entity, you can configure on top of an API by executing the following request on your Kong server:

$ curl -X POST http://kong:8001/apis/{api}/plugins \
    --data "name=response-transformer"  \
    --data "config.remove.headers=x-toremove, x-another-one" \
    --data "config.remove.json=json-key-toremove, another-json-key" \
    --data "config.add.headers=x-new-header:value,x-another-header:something" \
    --data "config.add.json=new-json-key:some_value, another-json-key:some_value" \
    --data "config.append.headers=x-existing-header:some_value, x-another-header:some_value"
  • api: either id or name of the API that this plugin configuration will target.

Enabling the plugin for a Consumer

You can use the http://localhost:8001/plugins endpoint to target Consumers:

$ curl -X POST http://kong:8001/plugins \
    --data "name=response-transformer" \
    --data "consumer_id={consumer_id}"  \
    --data "config.remove.headers=x-toremove, x-another-one" \
    --data "config.remove.json=json-key-toremove, another-json-key" \
    --data "config.add.headers=x-new-header:value,x-another-header:something" \
    --data "config.add.json=new-json-key:some_value, another-json-key:some_value" \
    --data "config.append.headers=x-existing-header:some_value, x-another-header:some_value"

Where consumer_id: The id of the Consumer we want to associate with this plugin.

You can combine adding consumer_id and service_id in the same request.

Once applied, any user with a valid credential can access the Service/API. To restrict usage to only some of the authenticated users, also add the ACL plugin (not covered here) and create whitelist or blacklist groups of users.

Global plugins

All plugins can be configured using the http:/kong:8001/plugins/ endpoint. A plugin which is not associated to any API, Service, Route or Consumer is considered "global", and will be run on every request. Read the Plugin Reference and the Plugin Precedence sections for more information.

Parameters

Here's a list of all the parameters which can be used in this plugin's configuration:

form parameterdefaultdescription
nameThe name of the plugin to use, in this case response-transformer
api_idThe id of the API which this plugin will target.
service_idThe id of the Service which this plugin will target.
route_idThe id of the Route which this plugin will target.
consumer_idThe id of the Consumer which this plugin will target.
config.remove.headers
optional

List of header names. Unset the header(s) with the given name.

config.remove.json
optional

List of property names. Remove the property from the JSON body if it is present.

config.replace.headers
optional

List of headername:value pairs. If and only if the header is already set, replace its old value with the new one. Ignored if the header is not already set.

config.replace.json
optional

List of property:value pairs. If and only if the parameter is already present, replace its old value with the new one. Ignored if the parameter is not already present.

config.add.headers
optional

List of headername:value pairs. If and only if the header is not already set, set a new header with the given value. Ignored if the header is already set.

config.add.json
optional

List of property:value pairs. If and only if the property is not present, add a new property with the given value to the JSON body. Ignored if the property is already present.

config.append.headers
optional

List of headername:value pairs. If the header is not set, set it with the given value. If it is already set, a new header with the same name and the new value will be set.

config.append.json
optional

List of property:value pairs. If the property is not present in the JSON body, add it with the given value. If it is already present, the two values (old and new) will be aggregated in an array.

Note: if the value contains a , then the comma separated format for lists cannot be used. The array notation must be used instead.

Order of execution

Plugin performs the response transformation in following order

remove --> replace --> add --> append

Examples

In these examples we have the plugin enabled on a Route. This would work similar for Services, or the depreciated API entity.

  • Add multiple headers by passing each header:value pair separately:
$ curl -X POST http://localhost:8001/routes/{route id}/plugins \
  --data "name=response-transformer" \
  --data "config.add.headers[1]=h1:v1" \
  --data "config.add.headers[2]=h2:v1"
upstream response headers proxied response headers
h1: v1
  • h1: v1
  • h2: v1

  • Add multiple headers by passing comma separated header:value pair:
$ curl -X POST http://localhost:8001/routes/{route id}/plugins \
  --data "name=response-transformer" \
  --data "config.add.headers=h1:v1,h2:v2"
upstream response headers proxied response headers
h1: v1
  • h1: v1
  • h2: v1

  • Add multiple headers passing config as JSON body:
$ curl -X POST http://localhost:8001/routes/{route id}/plugins \
  --header 'content-type: application/json' \
  --data '{"name": "response-transformer", "config": {"add": {"headers": ["h1:v2", "h2:v1"]}}}'
upstream response headers proxied response headers
h1: v1
  • h1: v1
  • h2: v1

  • Add a body property and a header:
$ curl -X POST http://localhost:8001/routes/{route id}/plugins \
  --data "name=response-transformer" \
  --data "config.add.json=p1:v1,p2=v2" \
  --data "config.add.headers=h1:v1"
upstream response headers proxied response headers:
h1: v2
  • h1: v2
  • h2: v1
h3: v1
  • h1: v1
  • h2: v1
  • h3: v1
upstream response JSON body proxied response body
{} {"p1" : "v1", "p2": "v2"}
{"p1" : "v2"} {"p1" : "v2", "p2": "v2"}

  • Append multiple headers and remove a body property:
$ curl -X POST http://localhost:8001/routes/{route id}/plugins \
  --header 'content-type: application/json' \
  --data '{"name": "response-transformer", "config": {"append": {"headers": ["h1:v2", "h2:v1"]}, "remove": {"json": ["p1"]}}}'
upstream response headers proxied response headers
h1: v1
  • h1: v1
  • h1: v2
  • h2: v1
upstream response JSON body proxied response body
{"p2": "v2"} {"p2": "v2"}
{"p1" : "v1", "p2" : "v1"} {"p2": "v2"}

Keep up with the latest features