apisix-插件开发
apisix源码下载, 并打开
克隆到自己项目文件夹下
git clone https://github.com/apache/apisix.git
git clone git@github.com:apache/apisix.git
源码找到echo, example-plugin两个插件进行参考
- 参考echo, example-plugin插件
- 复制example-plugin插件, 起一个名字, plugin-test
- 清除多余的内容
local ngx = ngx
local core = require("apisix.core")
local plugin = require("apisix.plugin")
local upstream = require("apisix.upstream")
local schema = {
type = "object",
}
local plugin_name = "plugin-test"
local _M = {
version = 0.1,
priority = 11111,
name = plugin_name,
schema = schema,
}
function _M.check_schema(conf, schema_type)
return core.schema.check(schema, conf)
end
function _M.init()
end
function _M.destroy()
end
function _M.rewrite(conf, ctx)
end
function _M.access(conf, ctx)
end
function _M.log(conf, ctx)
end
return _M
开始开发
这里先介绍使用apisix默认使用的lua语言进行开发
后续会提供其他语言的插件开发
了解插件的执行阶段
确认好需求, 根据需求, 确认需要在插件的哪个阶段进行开发
- rewrite
- 可以拿到请求url, 请求头, 请求体
- 可以修改响应状态码, 响应体
- access
- 同rewrite
- header_filter
- 不可以获得响应体
- 不可以修改响应体
- 可以获得、修改(响应头、响应状态码)
- body_filter
- 可以获得响应体
- 可以修改响应体
- 可以获得响应头、响应状态码
- 不可以修改响应头、响应状态码
参考文章
apisix插件开发
https://apisix.apache.org/zh/docs/apisix/plugin-develop
https://apisix.apache.org/zh/blog/2022/02/16/file-logger-api-gateway/
lua语言语法
https://www.runoob.com/lua/lua-tutorial.html
注意
开发插件目录, /apisix/apisix/plugins/
如果只开发一个lua文件, 则直接放在此目录即可
如果有文件夹的添加, 需要修改 Makefile 文件, 编译一下
参考: https://apisix.apache.org/zh/docs/apisix/plugin-develop/#插件命名,优先级和其他
实战
我想在把所有的请求添加一个请求头plugin-header, 值为hello
第一步, 修改基本属性
修改插件基本属性, 名称, 版本, 优先级(数字越高越先执行)
local schema = {
type = "object",
}
local plugin_name = "plugin-test"
local _M = {
version = 0.1,
priority = 11111,
name = plugin_name,
schema = schema,
}
第二步, 开发
添加请求头, 可以在rewrite阶段就可以完成, 所以代码如下
log阶段打印所有的请求头
function _M.rewrite(conf, ctx)
core.request.set_header(ctx, "plugin-header", "hello")
end
function _M.log(conf, ctx)
local headers = ngx.req.get_headers()
core.log.warn("headers: ", core.json.encode(headers))
end
第三步, 放入插件
注意: 我这里是docker启动, 所以需要先启动docker, 然后再放入插件, 修改配置, 然后重启
对于直接部署在机器上的apisix, 可以放入插件, 修改配置, 然后再启动
本地docker启动apisix, 参考: https://www.cnblogs.com/loseself/p/16147243.html
# 放入插件
# 获取docker 容器id
docker ps -a
# 移动插件
docker cp 根目录/apisix/apisix/plugins/plugin-test.lua 容器id:/usr/local/apisix/apisix/plugins
第四步, 修改apisix配置并重新启动
# 有docker的进入docker
vi /usr/local/apisix/conf/config-default.yaml
# 搜索 plugins, 填入插件
- plugin-test
# 重新启动
apisix restart
# 或者使用docker重新启动即可
第五步, 绑定路由测试
这里使用apisix的docker提供的web1上游
# 记得替换自己的机器ip
IP=xxx
# 访问原有的web1服务
curl -i -X GET http://$IP:9081/hello
# 绑定路由
curl http://$IP:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"plugins": {
"plugin-test": {
}
},
"upstream": {
"nodes": {
"192.168.63.49:9081": 1
},
"type": "roundrobin"
},
"uri": "/hello"
}'
# 访问代理后的web1
curl -i -X GET http://$IP:9080/hello
# 查看apisix日志
cd /usr/local/apisix/logs && tail -f error.log
变量介绍
ctx(类似于netty的ChannelHandlerContext ctx)
这个 Lua 表可以用来存储基于请求的 Lua 环境数据,其生存周期与当前请求相同 (类似 Nginx 变量)。
方法介绍
请注意方法的使用阶段
获取所有的请求头, table数据类型
local headers = ngx.req.get_headers()
添加请求头
core.request.set_header(ctx, "key", "value")
获取单独请求头
local time = core.request.header(ctx, key)
获取请求体
core.request.get_body()
获取响应头
local value = ngx.header[key]
添加响应头
ngx.header[key] = value
获取响应体
local body = ngx.arg[1]