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"]
HeaderAction
ServerRemove (hide stack)
X-Powered-ByRemove
Strict-Transport-SecurityAdd
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

BackendClient SeesReason
500503Hide internals
502 (upstream down)503 + Retry-AfterRetry hint
418400Normalize obscure codes
301308Preserve method

4. Using Response Templates

Example: Error template

{
  "error": {
    "code": "{{ status }}",
    "message": "{{ message }}",
    "request_id": "{{ request_id }}",
    "timestamp": "{{ now }}"
  }
}

5. Converting Response Formats

FromToTool
XMLJSONxml2json plugin
SOAPJSONSOAP-to-REST adapter
ProtobufJSONgrpc-transcoding
CSVJSONCustom Lua

6. Setting Default Response Values

MissingDefault
Empty body{} or []
No Content-Typeapplication/json
No request_idGenerate 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

PatternDescription
Parallel fanoutCall N services concurrently
Merge by keyCombine on shared id
Nested embedInline related resources
Partial failureReturn 206 with errors[]

9. Setting Response Compression

SettingValue
min_size1KB (below not worth CPU)
levelgzip 4-6, brotli 4-5
typesJSON, HTML, CSS, JS, SVG, text
ExcludeImages, video, already compressed

10. Configuring Response Caching Headers

HeaderUse
Cache-Control: public, max-age=3600CDN + browser
Cache-Control: private, no-storeSensitive data
ETagConditional GET
Last-ModifiedTimestamp validation
Vary: Accept-EncodingCache per encoding
stale-while-revalidate=60Serve stale during refresh