Apache APISIX 插件开发完全指南
前言
Apache APISIX 作为云原生 API 网关,其插件系统是其最强大的功能之一。本文将全面介绍如何在 APISIX 中开发自定义插件,从基础概念到高级功能,帮助开发者快速掌握插件开发的核心要点。
插件开发基础
插件放置路径
APISIX 提供了灵活的插件加载机制,开发者可以通过两种方式扩展功能:
- 直接修改源代码(不推荐):这种方式虽然直接,但不利于后续升级维护
- 通过配置加载自定义代码(推荐):在
conf/config.yaml中配置extra_lua_path和extra_lua_cpath
推荐的项目目录结构示例:
├── custom_plugins
│ └── apisix
│ ├── plugins
│ │ └── my-plugin.lua
│ └── stream
│ └── plugins
│ └── my-stream-plugin.lua
对应的配置示例:
apisix:
extra_lua_path: "/path/to/custom_plugins/?.lua"
覆盖现有函数
如果需要修改 APISIX 内置函数的行为,可以通过 lua_module_hook 配置实现:
apisix:
extra_lua_path: "/path/to/custom_plugins/?.lua"
lua_module_hook: "my_hook"
my_hook.lua 文件可以实现全局函数替换,这种方式比直接修改源代码更加优雅。
插件开发核心要素
插件基本结构
每个插件都需要定义一些基本属性:
local plugin_name = "my-plugin"
local _M = {
version = 0.1,
priority = 10, -- 优先级,数值越大执行越早
name = plugin_name, -- 插件名称,必须唯一
schema = schema, -- 配置的JSON Schema
type = "auth", -- 可选,如果是认证插件需要设置为auth
}
优先级机制
APISIX 插件执行遵循优先级规则:
- 同一阶段内,priority 值大的插件先执行
- 建议自定义插件使用 1-99 之间的优先级
- 可通过控制API查看现有插件优先级
插件启用配置
在 conf/config.yaml 中启用插件:
plugins:
- existing-plugin
- my-plugin
配置管理与校验
Schema 定义
每个插件都需要定义配置的 JSON Schema:
local schema = {
type = "object",
properties = {
timeout = {type = "number", minimum = 0},
host = {type = "string"},
endpoints = {type = "array", minItems = 1},
},
required = {"timeout", "host"},
}
配置校验
实现 check_schema 方法进行配置校验:
function _M.check_schema(conf)
return core.schema.check(schema, conf)
end
对于认证插件,还需要定义 consumer_schema 来校验 Consumer 资源配置。
敏感数据加密
APISIX 3.1+ 支持敏感字段自动加密存储:
encrypt_fields = {"password", "db.connection.password"}
需要在 config.yaml 中配置加密密钥:
apisix:
data_encryption:
enable: true
keyring:
- first-encryption-key
- backup-encryption-key
插件执行阶段
APISIX 插件可以在以下阶段执行:
- rewrite:重写阶段,主要用于认证逻辑
- access:访问阶段,大部分业务逻辑在此执行
- header_filter:响应头处理阶段
- body_filter:响应体处理阶段
- log:日志记录阶段
注意事项
- 在 rewrite 和 access 阶段不能直接调用
ngx.exit - 如需退出,应返回状态码和正文,由插件引擎处理
- APISIX 还提供了额外的
delayed_body_filter阶段
核心开发逻辑
处理函数参数
插件处理函数接收两个关键参数:
- conf:当前路由的插件配置
- ctx:请求上下文,包含丰富的信息
调试时可输出这些参数:
function _M.access(conf, ctx)
core.log.warn("conf: ", core.json.encode(conf))
core.log.warn("ctx: ", core.json.encode(ctx, true))
end
高级功能
注册公共API
插件可以暴露公共API:
function _M.api()
return {
{
methods = {"POST"},
uri = "/apisix/my-plugin/action",
handler = handle_action,
}
}
end
需要通过 public-api 插件来暴露这些接口。
注册控制API
只暴露给本地或内网的API:
function _M.control_api()
return {
{
methods = {"GET"},
uris = {"/v1/plugin/my-plugin/status"},
handler = get_status,
}
}
end
自定义变量
注册全局可用变量:
core.ctx.register_var("a6_plugin_value", function(ctx)
return ctx.var.my_custom_value
end)
注册后可在任何地方使用 $a6_plugin_value 引用。
测试开发
测试框架
APISIX 使用 test-nginx 框架,测试用例通常包括:
- 配置部分:Nginx location 配置
- 请求部分:发送的HTTP请求
- 断言部分:对响应的各种检查
示例测试用例:
=== TEST 1: basic functionality
--- config
location /t {
content_by_lua_block {
local plugin = require("apisix.plugins.my-plugin")
local ok, err = plugin.check_schema({timeout = 1})
if not ok then
ngx.say(err)
end
ngx.say("ok")
}
}
--- request
GET /t
--- response_body
ok
--- no_error_log
[error]
最佳实践
- 命名规范:插件名应具有唯一性,建议使用小写和连字符
- 错误处理:完善的错误检查和日志记录
- 性能考虑:避免在插件中执行耗时操作
- 资源清理:如有初始化操作,实现对应的destroy方法
- 文档完善:为插件编写清晰的使用文档
总结
Apache APISIX 的插件系统提供了强大的扩展能力,通过本文的介绍,开发者可以掌握从基础到高级的插件开发技巧。合理设计的插件可以大大增强 APISIX 的功能,满足各种业务场景的需求。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



