Skip to main content
Version: 3.17

exit-transformer

描述#

exit-transformer 插件拦截由 APISIX 自身生成的响应——例如认证失败、限流拒绝或上游错误——并在发送给客户端之前,通过用户自定义的 Lua 函数对其进行转换。

该插件通过注册回调函数的方式工作:当 core.response.exit() 被调用时,回调函数依次执行,接收响应的 (状态码, 响应体, 响应头) 作为参数,并返回(可能已修改的)值。多个函数可以链式执行,前一个函数的输出作为下一个函数的输入。

note

该插件仅转换由 APISIX 自身 core.response.exit() 机制产生的响应,不会转换来自上游服务的响应。

属性#

名称类型必选项默认值有效值描述
functionsarray[string]Lua 函数源码字符串数组。每个字符串必须是一个完整的 Lua 代码块,该代码块须返回一个函数。函数接收 (status_code, body, headers) 三个参数,并必须返回 status_code, body, headers(修改后的或原始值)。若函数抛出异常,错误将被记录到日志,原始值将被传递给下一个函数。

每个 Lua 函数字符串必须是一个可求值为函数的代码块,函数签名如下:

return (function(code, body, header)
-- 按需修改 code、body 或 header
return code, body, header
end)(...)

示例#

以下示例演示了如何在不同场景中使用 exit-transformer 插件。

note
admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')

重映射状态码#

以下示例演示如何将 401 Unauthorized 响应重映射为 403 Forbidden

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${admin_key}" \
-d '{
"id": "exit-transformer-route",
"uri": "/anything",
"plugins": {
"key-auth": {},
"exit-transformer": {
"functions": [
"return (function(code, body, header) if code == 401 then return 403, body, header end return code, body, header end)(...)"
]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {"httpbin.org:80": 1}
}
}'

发送一个不带 API Key 的请求:

curl -i "http://127.0.0.1:9080/anything"

将收到 403 Forbidden 响应,而非默认的 401 Unauthorized

统一错误响应格式#

以下示例演示如何将所有错误响应体重写为统一的 JSON 格式,并添加自定义响应头。

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${admin_key}" \
-d '{
"id": "exit-transformer-route",
"uri": "/anything",
"plugins": {
"key-auth": {},
"exit-transformer": {
"functions": [
"return (function(code, body, header) if code and code >= 400 then header = header or {} header[\"X-Error-Code\"] = tostring(code) body = {error = true, status = code, message = (type(body) == \"table\" and body.message) or \"request failed\"} end return code, body, header end)(...)"
]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {"httpbin.org:80": 1}
}
}'

发送一个不带 API Key 的请求:

curl -i "http://127.0.0.1:9080/anything"

将收到带有统一 JSON 格式响应体和 X-Error-Code: 401 响应头的 401 响应:

{"error":true,"status":401,"message":"Missing API key in request"}