This plugin transforms the response body from upstream by adding additional fields or changing the existing one.
Full config for kubernetes kong plugin
apiVersion: configuration.konghq.com/v1
config:
upstream:
uri: http://upstream
host_header: upstream
paths:
- path: /v1/data/[^/]+
resources_to_extend:
- data_paths:
- path: "$.service-a"
id_path: "$.service-a.id"
api:
url: "http://service-a/api/v1/data/"
data_path: "$"
id_key: email
- data_paths:
- id_path: "$.service-b.id"
path: "$.service-b"
- id_path: "$.service-b_2.id"
path: "$.service-b_2"
api:
id_key: id
url: "http://service-b/v1/data/"
data_path: "$"
- path: /v1/data
upstream_data_path: "$.content"
resources_to_extend:
- data_paths:
- path: "$.service-a"
id_path: "$.service-a.id"
api:
url: "http://service-a/api/v1/data"
data_path: "$.content"
query_param_name: ids
id_key: id
- data_paths:
- id_path: "$.service-b.id"
path: "$.service-b"
api:
url: "http://service-b/api/v1/data"
data_path: "$.content"
query_param_name: ids
id_key: id
- path: /v1/data/(?<id>.*)/print
methods:
- GET
upstream:
uri: http://printing
host_header: printing
path: /data
method: POST
request:
extend_with_auth_token: true
overwrite_body: |-
{
"object": {
"id": "${id}",
"user": "${auth_token.ext.user.id}"
}
}
resources_to_extend:
- data_paths:
- path: "$.object"
id_path: "$.object.id"
api:
id_key: id
url: "http://service-b/v1/data/"
data_path: "$"
- data_paths:
- path: "$.configuration"
add_missing: true,
api:
url: "http://service-a/v1/data/"
kind: KongPlugin
metadata:
name: api-response-merger-upstream
namespace: default
plugin: api-response-merger
This paragraph will show how usage of this plugins looks like. We assume that there are 3 REST APIs which can be querd using below example
We have upstream service that returns response with only ids of resources from service-a and service-b
$ curl -X GET http://upstream/v1/data/upstream-1
{
"id": "uptream-1",
"service-a": {
"id": "a"
},
"service-b": {
"id": "b"
},
"upstream-data": {
"foo": "bar"
}
}
Response from service-a
$ curl -X GET http://service-a/api/v1/data/data/a
{
"id": "a",
"data": {
"text": "data from service a"
}
}
Response from service-b
$ curl -X GET http://service-b/api/v1/data/b
{
"id": "b",
"data": {
"text": "data from service b",
"foo-b": "bar"
}
}
This plugin will allow to change upstream response by extending it respone of data from service-a and service-b. See example below
$ curl -X GET http://kong/v1/data/upstream-1
{
"id": "upstream-1",
"service-a": {
"id": "a",
"data": {
"text": "data from service a"
}
},
"service-b": {
"id": "b",
"data": {
"text": "data from service b",
"foo-b": "bar"
}
},
"upstream-data": {
"foo": "bar"
}
}
Configure this plugin on a Service by making the following request:
$ curl -X POST http://kong:8001/services/{service}/plugins \
--data "name=api-response-merger"
service
: the id
or name
of the Service that this plugin configuration will target.
Configure this plugin on a Route with:
$ curl -X POST http://kong:8001/routes/{route_id}/plugins \
--data "name=api-response-merger"
route_id
: the id
of the Route that this plugin configuration will target.
You can use the http://localhost:8001/plugins
endpoint to enable this plugin on specific Consumers:
$ curl -X POST http://kong:8001/plugins \
--data "name=api-response-merger" \
--data "consumer_id={consumer_id}"
Where consumer_id
is the id
of the Consumer we want to associate with this plugin.
You can combine consumer_id
and service_id
in the same request, to furthermore narrow the scope of the plugin.
form parameter | default | description |
---|---|---|
name |
The name of the plugin to use, in this case request-transformer |
|
service_id |
The id of the Service which this plugin will target. | |
route_id |
The id of the Route which this plugin will target. | |
enabled |
true |
Whether this plugin will be applied. |
consumer_id |
The id of the Consumer which this plugin will target. | |
config.upstream.uri |
Base upstream uri | |
config.upstream.host_header |
Host header which should be passed to upstream | |
config.upstream.path |
Overwrites path to upstream | |
config.upstream.path_prefix |
`` | Prefix for path to upstream |
config.upstream.method |
Method used for upstream call (by default method from the request) | |
config.paths |
List of paths on which plugin should merge response | |
config.paths[0].path |
Regular expression for path | |
config.paths[0].upstream |
Upstream configuration which overrides base upstream config (see config.upstream) | |
config.paths[0].upstream_data_path |
$ |
JSON path for data to transform |
config.paths[0].resources_to_extend |
List of resources to change/expand | |
config.paths[0].resources_to_extend[0].data_paths |
List of JSON paths to change - at least one required | |
config.paths[0].resources_to_extend[0].data_paths[0].path |
JSON path for key where to put response of resource upstream - path is required | |
config.paths[0].resources_to_extend[0].data_paths[0].id_path |
JSON path for id of resource in upstream response | |
config.paths[0].resources_to_extend[0].api |
Object with config for resource upstream | |
config.paths[0].resources_to_extend[0].api.url |
Adress for api from given resource can be retrieved, url can be interpolated with values from the body (response or request - currently transformed, e.g. for { "object": {"id": "id_value" } } the following expression can be used ${object.id} e.g. url = http://resource-service/resources/${object.id}/other-resources) |
|
config.paths[0].resources_to_extend[0].api.data_path |
$ |
JSON path for resource data |
config.paths[0].resources_to_extend[0].api.query_param_name |
nil | Query string parameter name when accessing multiple resources |
config.paths[0].resources_to_extend[0].allow_missing |
false | Flag indicating if merger should returns error when resource is missing. Default false |
config.paths[0].resources_to_extend[0].add_missing |
false | Flag indicating if merger should try adding the whole upstream body under the path if the id is missing |
config.paths[0].request.overwrite_body |
nil | New request body used for the upstream. It is interpolated with the captures for the path mapping (named variables are supported, see https://github.com/openresty/lua-nginx-module#ngxrematch) |
config.paths[0].request.resources_to_extend |
nil | List of resources to be changed/expanded (see details above) |
config.paths[0].request.extend_with_auth_token |
false | Whether the auth token should be used for interpolation of request body - if true, it can be accessed by "auth_token" param, e.g. { "object": {"user_id": "${auth_token.ent.user.id}" } } |