Configuring Response Transformation
1. Transforming Response Headers
Example: Strip internal headers
plugins:
- name: response-transformer
config:
remove:
headers: ["X-Internal-Trace", "Server", "X-Powered-By"]
add:
headers: ["X-Gateway:edge-v2", "Cache-Control:no-store"]
| Header | Action |
|---|---|
Server | Remove (hide stack) |
X-Powered-By | Remove |
Strict-Transport-Security | Add |
X-RateLimit-* | Add for clients |
2. Modifying Response Body
Example: Wrap response in envelope
local cjson = require "cjson"
local body = cjson.decode(kong.service.response.get_raw_body())
local wrapped = {
data = body,
meta = { request_id = kong.ctx.shared.request_id, ts = ngx.now() }
}
kong.response.set_raw_body(cjson.encode(wrapped))
3. Implementing Response Status Code Mapping
| Backend | Client Sees | Reason |
|---|---|---|
| 500 | 503 | Hide internals |
| 502 (upstream down) | 503 + Retry-After | Retry hint |
| 418 | 400 | Normalize obscure codes |
| 301 | 308 | Preserve method |
4. Using Response Templates
Example: Error template
{
"error": {
"code": "{{ status }}",
"message": "{{ message }}",
"request_id": "{{ request_id }}",
"timestamp": "{{ now }}"
}
}
5. Converting Response Formats
| From | To | Tool |
|---|---|---|
| XML | JSON | xml2json plugin |
| SOAP | JSON | SOAP-to-REST adapter |
| Protobuf | JSON | grpc-transcoding |
| CSV | JSON | Custom Lua |
6. Setting Default Response Values
| Missing | Default |
|---|---|
| Empty body | {} or [] |
| No Content-Type | application/json |
| No request_id | Generate UUID |
7. Implementing Response Filtering
Example: Field allowlist by scope
local scopes = kong.ctx.shared.jwt_payload.scopes
local body = cjson.decode(kong.service.response.get_raw_body())
if not scopes["pii:read"] then
body.email = nil
body.phone = nil
body.ssn = nil
end
kong.response.set_raw_body(cjson.encode(body))
8. Configuring Response Aggregation
| Pattern | Description |
|---|---|
| Parallel fanout | Call N services concurrently |
| Merge by key | Combine on shared id |
| Nested embed | Inline related resources |
| Partial failure | Return 206 with errors[] |
9. Setting Response Compression
| Setting | Value |
|---|---|
min_size | 1KB (below not worth CPU) |
level | gzip 4-6, brotli 4-5 |
types | JSON, HTML, CSS, JS, SVG, text |
| Exclude | Images, video, already compressed |
10. Configuring Response Caching Headers
| Header | Use |
|---|---|
Cache-Control: public, max-age=3600 | CDN + browser |
Cache-Control: private, no-store | Sensitive data |
ETag | Conditional GET |
Last-Modified | Timestamp validation |
Vary: Accept-Encoding | Cache per encoding |
stale-while-revalidate=60 | Serve stale during refresh |