使用 OpenResty 和 Nginx Lua 修改 InfluxDB API 的返回结构

文章目录

在 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 压缩:

  1. 清除请求头: 在 location 中添加以下配置:

    more_clear_input_headers Accept-Encoding;
    
  2. 关闭请求头转发

    proxy_pass_request_headers off;
    
  3. 使用 Lua zlib 库解压响应: 下载并安装 Lua zlib,然后在 Lua 代码中使用它来解压响应数据。

总结

通过上述配置和方法,可以有效地将 InfluxDB API 的返回结构转换为统一的格式,便于 API 平台的处理和使用。此方法不仅解决了数据乱码的问题,还提高了 API 的一致性和可靠性。


也可以看看