在现代应用开发中,API 是系统与服务集成的关键基础。然而,不同系统间常常会遇到 API 要求不一致、数据格式不同、安全要求不满足等问题。此时,利用 API 网关灵活地修改请求和响应,是最有效的解决方式。
像 Kong Gateway 这样的 API 网关不仅仅是 API 管理工具。它在流量控制过程中,提供了强大的请求与响应内容定制能力。例如,可以实现如下操作:
Header 头部
可以为客户端请求头添加认证信息或自定义值,也可以编辑响应头,加入缓存控制或安全相关信息。
Body 转换
可以加工请求体,使其符合上游服务的格式要求,或过滤响应体内容,去除不需要的数据。
状态码变更
可根据 API 行为修改状态码,灵活控制错误处理或重定向。
数据格式转换
如果老系统要求 XML,新系统用 JSON,可以在 API 网关动态转换数据格式,实现兼容。
加密与解密
根据安全要求,对请求和响应数据进行加密或解密,提升通信安全性。
这些变更都无需改动 API 客户端或后端。API 网关在系统边界操作,既能灵活定制,又能最大限度降低对其他系统的影响。
如何用 Kong 修改请求与响应#
本文将详细介绍如何用 Kong Gateway 实现上述变更。
Kong Gateway 提供的 Request Transformer 和 Response Transformer 插件,是便捷定制请求与响应内容的利器。通过这些插件,可以灵活处理请求/响应头和 Body,满足系统集成和特定 API 需求。
主要功能#
Request Transformer 插件主要功能:
- 添加、删除、覆盖请求头
- 添加、删除、覆盖查询参数
- 添加或删除请求体字段
Response Transformer 插件主要功能:
结合这些功能,可以灵活控制 API 流量。
插件配置#
首先,创建测试 Service 和 Route。本例用回显请求的 API,方便观察请求被修改的效果。
1
2
3
4
5
6
7
| curl -i -X POST http://localhost:8001/services/ \
--data name=echo_service \
--data url=http://httpbin.org/anything
curl -i -X POST http://localhost:8001/services/echo_service/routes/ \
--data name=echo_route \
--data paths=/echo
|
然后启用 request transformer 插件,并设置如下规则:
- 添加 Authorization 头
- 删除 debug 查询参数
1
2
3
4
| curl -i -X POST http://localhost:8001/services/echo_service/plugins \
--data "name=request-transformer" \
--data "config.add.headers=Authorization: Bearer abc123" \
--data "config.remove.querystring=debug"
|
效果验证#
发送如下请求:
1
| http localhost:8000/echo\?debug=aaa\&uuid=2345
|
会收到如下响应:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| HTTP/1.1 200 OK
...
{
"args": {
"uuid": "2345"
},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Authorization": "Bearer abc123",
"Host": "httpbin.org",
"User-Agent": "HTTPie/2.6.0",
"X-Amzn-Trace-Id": "Root=1-6762e0e7-74dc18834a309ed8391d33a5",
"X-Forwarded-Host": "localhost",
"X-Forwarded-Path": "/echo",
"X-Forwarded-Prefix": "/echo",
"X-Kong-Request-Id": "fc4da81ce6d1583d6a5d52531caff043"
},
"json": null,
"method": "GET",
"origin": "172.21.0.1, x.x.x.x",
"url": "http://localhost/anything?uuid=2345"
}
|
可以看到,请求被按预期修改:
- Header 中新增了
"Authorization": "Bearer abc123",
- URL 参数
debug=aaa
被删除
更多玩法可参考 插件官方文档。
exit transformer 插件允许用 Lua 函数自定义 Kong Gateway 的响应终止消息。它可以修改消息、状态码、头部,甚至完全重构响应结构。
该插件会在返回 4xx 或 5xx 响应时执行配置的代码。
:::note warn
目前该插件只对 Kong 内部错误生效,不处理上游服务的错误。
:::
首先注册测试服务和路由。
1
2
3
4
5
6
| curl -i -X POST http://localhost:8001/services \
--data name=example.com \
--data url='https://httpbin.konghq.com'
curl -i -X POST http://localhost:8001/services/example.com/routes \
--data 'paths=/example'
|
将如下脚本保存为 transform.lua
,插件会执行它:
1
2
3
4
5
6
7
8
9
10
11
12
| return function(status, body, headers)
if not body or not body.message then
return status, body, headers
end
headers = { ["x-some-header"] = "some value" }
local new_body = {
error = true,
status = status,
message = body.message .. ", arr!",
}
return 200, new_body, headers
end
|
该脚本做了如下变更:
- Header 中新增
["x-some-header"] = "some value"
- Body 结尾追加
arr
- 响应状态码强制为
200
用上述 transform.lua
启用 exit-transformer 插件:
1
2
3
| curl -X POST http://localhost:8001/services/example.com/plugins \
-F "name=exit-transformer" \
-F "[email protected]"
|
添加 key-auth 插件以触发错误响应:
1
2
| curl -X POST http://localhost:8001/services/example.com/plugins \
--data "name=key-auth"
|
请求 /example
以获取自定义错误。此时因未提供认证(API key),消息体返回 401,但客户端实际收到 200 响应。
1
2
3
4
5
6
7
8
9
10
| http localhost:8000/example
HTTP/1.1 200 OK
...
x-some-header: some value
{
"error": true,
"message": "No API key found in request, arr!",
"status": 401
}
|
API 网关是系统集成和需求适配的关键工具。用 Kong Gateway,可以动态修改请求/响应头、Body、状态码,支持数据格式转换和安全增强。结合标准插件和 Lua 脚本,能极大提升系统的灵活性和效率。