在 API 平台中,接口的返回结构统一性至关重要。许多 API 服务需要通过一个标准化的接口返回数据,以确保能够被有效处理。如果你正在使用 InfluxDB 的 API 并希望将其返回结构统一为如下格式:
{
"code": 0,
"msg": "",
"data": {}
}
那么本文将介绍如何使用 OpenResty 和 Nginx Lua 实现这一目标。
Nginx 配置文件示例
首先,你需要安装 OpenResty,然后创建一个配置文件 ngx_lua_restructure_influxdb_response.conf
。以下是具体配置示例:
upstream influxdb {
server 127.0.0.1:8086;
}
server {
listen 18086;
proxy_pass_request_headers off;
location / {
proxy_pass https://influxdb/query;
}
location /query {
add_header Content-Type 'application/json; charset=utf-8';
content_by_lua_block {
local method_map = {
GET = ngx.HTTP_GET,
POST = ngx.HTTP_POST,
}
ngx.req.read_body()
local method = method_map[ngx.req.get_method()]
local data = ngx.req.get_body_data()
local args = ngx.req.get_uri_args()
local res = ngx.location.capture("/", {method=method, data=data, args=args})
local cjson = require "cjson"
local new_body = {}
if res.status ~= ngx.HTTP_OK then
new_body["code"] = res.status
else
new_body["code"] = 0
end
new_body["msg"] = ''
new_body["data"] = cjson.decode(res.body)
ngx.say(cjson.encode(new_body))
}
}
}
测试与结果
InfluxDB 的 API 运行在 8086 端口,直接请求的返回结果类似如下:
curl -Gs '100.113.164.108:8086/query?db=data&q=SELECT+*+FROM+cpu+limit+1&pretty=true'
返回结果为:
{
"results": [
{
"statement_id": 0,
"series": [
{
"name": "cpu",
"columns": [ ... ],
"values": [ ... ]
}
]
}
]
}
经过配置后,访问 18086 端口将返回格式化的结果:
curl -Gs '100.113.164.108:18086/query?db=db_zhiyun&q=SELECT * FROM cpu limit 1&pretty=true' | python -m json.tool
返回结果如下:
{
"code": 0,
"data": {
"results": [ ... ]
},
"msg": ""
}
解决的问题
在实现过程中遇到的问题是,API 平台请求返回的数据出现乱码。通过 ngx.req.raw_header()
检查后发现,API 平台的请求中包含 Accept-Encoding: gzip, deflate
,而这导致了捕获的响应被 gzip 压缩,最终在解析 JSON 时出错。
解决方案
为了确保正确获取响应数据,可以使用以下几种方法来禁用 gzip 压缩:
清除请求头: 在 location 中添加以下配置:
more_clear_input_headers Accept-Encoding;
关闭请求头转发:
proxy_pass_request_headers off;
使用 Lua zlib 库解压响应: 下载并安装 Lua zlib,然后在 Lua 代码中使用它来解压响应数据。
总结
通过上述配置和方法,可以有效地将 InfluxDB API 的返回结构转换为统一的格式,便于 API 平台的处理和使用。此方法不仅解决了数据乱码的问题,还提高了 API 的一致性和可靠性。