APISIX 自定义插件本身不难,真正容易卡住的通常是“写完之后怎么让它在 Admin 和 Dashboard 里都正常工作”。这次的场景很简单:需要补一个官方现成插件不满足的能力,在请求和响应阶段都打上自己的标记。
下面按“先写、再挂载、再验证、最后补齐 Dashboard 配置”的顺序整理一遍。看完你可以快速判断:如果插件通过 Admin API 已经生效,但 Dashboard 仍提示不存在,问题大概率就不在 Lua 代码,而在 `schema.json` 的同步链路上。
为什么要自己写 APISIX 插件
原始需求并不复杂:对 cookie 相关请求做定制处理。排查 APISIX 自带插件后,发现现有能力不完全匹配,因此直接补一个自定义插件会更省事。
示例插件做的事情也很明确:
- 在请求阶段写入请求头;
- 在响应阶段写入响应头;
- 用最小实现先跑通插件开发与发布流程。
Lua 插件怎么写
插件开发规范可以直接参考 APISIX 官方文档:https://apisix.apache.org/docs/apisix/plugin-develop/。这里保留原文中的最小示例,便于直接对照。
local core = require("apisix.core")
local plugin_name = "cookie-plugin"
local schema = {
type = "object",
properties = {},
}
local _M = {
version = 0.1,
priority = 0, -- 设置插件优先级
name = plugin_name,
schema = schema,
}
function _M.check_schema(conf)
return core.schema.check(schema, conf)
end
function _M.access(conf, ctx)
-- 添加请求头
core.request.set_header(ctx, "cookie-plugin", "success")
end
function _M.header_filter(conf, ctx)
-- 添加响应头
core.response.set_header("cookie-plugin", "success")
end
return _M
这个最小插件包含哪些关键点
plugin_name定义插件名,这个名字后面要和文件名、配置项保持一致。schema这里是一个空配置对象,说明当前插件不要求额外参数。check_schema负责校验插件配置是否合法。access在请求阶段执行,这里通过core.request.set_header写入请求头。header_filter在响应头阶段执行,这里通过core.response.set_header写入响应头。
这个例子虽然简单,但足够验证一个自定义插件是否已被 APISIX 正常加载。
让 Admin 先识别你的插件
部署阶段先区分两个角色:

- Admin:提供 API 管理能力;
- Dashboard:提供可视化配置能力。
很多时候插件“能调 API 但 Dashboard 看不到”,就是这两部分只完成了一半。
1. 把 Lua 文件放到插件目录
先把脚本文件名改成插件名对应的形式,例如上面的 cookie-plugin.lua,然后放到 Admin 服务的插件目录。常见路径是:
/usr/local/apisix/apisix/plugins/
如果你使用的是自定义目录,也可以通过 config.yaml 额外指定路径,具体方式见官方插件开发文档。
2. 在 config.yaml 中注册插件
仅仅把 Lua 文件放进去还不够,还需要在 config.yaml 的 plugins 列表里显式加入插件名:
plugins:
- cookie-plugin
这里有一个很容易忽略的坑:如果你只写了这一项,而没有把 config-default.yaml 里的默认插件列表一并带过来,后续可能会出现“自定义插件能用,但官方插件都没了”的情况。
更稳妥的做法是:以默认插件列表为基础,把 cookie-plugin 追加进去,而不是只保留这一项。
3. 用热加载刷新插件
改完配置后,当然可以通过 apisix stop 再 apisix start 的方式重启服务,但 APISIX 也提供了热加载接口,适合直接刷新插件:
curl --location --request PUT 'http://自己的IP:端口/apisix/admin/plugins/reload'
--header 'X-API-KEY: 你自己的key'
这一步完成后,Admin 侧通常已经能识别到新插件。
怎么验证插件已经生效
最直接的方式是给一个测试路由挂上这个插件,然后实际发起请求检查响应头。
先创建路由:
curl http://127.0.0.1:9180/apisix/admin/routes/1 -X PUT -d '
{
"uri": "/example",
"plugins": {
"cookie-plugin": {}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
然后发起请求:
curl -i http://127.0.0.1:9080/example
如果响应里已经出现 cookie-plugin: success,就说明插件至少在网关执行链路中已经跑通了。
换句话说,到这一步你已经可以确认三件事:
- Lua 插件文件被正确加载;
- 插件名和路由配置对应无误;
header_filter阶段确实执行成功。
为什么 Dashboard 里还是找不到插件
如果 Admin API 已经能正常使用插件,但 Dashboard 里配置时报“插件不存在”,问题通常不在代码,而在 schema.json。

schema.json 是 Dashboard 做可视化表单渲染和插件识别的重要依据。新插件没有出现在这个文件里时,Dashboard 就不知道它是什么,自然也无法展示。
生成 schema.json
这个文件不需要手写,可以直接从接口导出:
curl 127.0.0.1:9090/v1/schema > schema.json
替换 Dashboard 配置并重启
把生成好的 schema.json 复制到 Dashboard 的 config 目录下进行替换,然后重启 Dashboard 服务。完成后,自定义插件通常就可以在可视化界面中正常显示和配置了。
这套流程里最容易踩的坑
- 插件文件名、插件名、配置项名称没有保持一致。
config.yaml只留下自定义插件,导致默认官方插件列表丢失。- 修改插件后没有执行热加载或重启,Admin 侧仍是旧状态。
- 只验证了 Admin API,没同步
schema.json,结果 Dashboard 中看不到插件。
如果你的目标只是“先把自定义插件跑起来”,做到 Admin 注册、热加载、路由验证这三步就够了;如果还要让运维或业务同学在 Dashboard 上可视化配置,那么 schema.json 同步和 Dashboard 重启就是最后不能省掉的一步。









