Day 09 / 共 20 天 · 第 2 周 路由/配置/数据面
schema 校验(守住配置质量)
昨天的对象存入前必须校验(不能存一条 uri 是数字的路由)。今天看 core/schema.lua 怎么用 JSON Schema 校验,以及"在写入端挡住坏配置"的设计——这是 APISIX 配置健壮性的保障。
📍 你在整条链的位置
六大对象 D8→
schema 校验(守门)→
上游 D10→
插件 W3
L01
垃圾进 → 垃圾出
🤔 运维手滑填了个非法配置,会怎样?
配置是人手写/程序生成的,难免出错:uri 写成数字、端口填字符串、必填字段漏了。如果不校验就存进 etcd,等请求处理时才崩——难排查、影响线上。
💡 在写入时就用 schema 严格校验,不合法直接拒
APISIX 在配置写入时(Admin API)就校验,不合法返回 400 + 清晰错误。"在源头挡住坏配置"比"运行时才发现"好一万倍。(对比上一站 Higress Console 的后端校验是空 TODO——APISIX 这里是真校验。)
L02
JSON Schema:数据的合同
APISIX 用 JSON Schema 描述"合法配置长什么样"。schema_def.lua 里的对象定义就是 JSON Schema:
_M.route = {
type = "object",
properties = {
uri = {type = "string"}, -- uri 必须是字符串
priority = {type = "integer", default = 0}, -- priority 是整数、默认 0
plugins = _M.plugins,
},
-- oneOf / required / dependencies 等约束
}
JSON Schema 是"数据的合同"
一套标准,声明"一个 JSON 对象允许有哪些字段、什么类型、哪些必填、取值范围"。校验器拿配置对照 schema 检查,不符就报错。好处:声明式(不用写一堆 if)、标准化(前后端/文档共用)、自带默认值填充。上一站 wasm-go/Higress Console 的插件配置也用 JSON Schema——网关界的通用语言。
L03
core.schema.check
core/schema.lua:59 的 check(schema, json):拿 schema 和数据,返回是否合法 + 错误信息。底层用 jsonschema 库(把 schema 编译成校验函数)。
读法:
check 被到处调用:Admin API 存对象前校验、插件加载配置时校验、consumer 凭据校验……一个统一的校验函数,配上各处的 schema 定义,覆盖整个配置系统。L04
schema 片段复用(DRY)
schema_def.lua 定义了很多可复用片段:host_def(:50)、ip_def(:69)、uri_def(:72,带正则 pattern)、health_checker(:300)、method_schema…
schema 也讲 DRY
"合法的 host""合法的 IP""合法的健康检查配置"这些片段被 route/service/upstream 反复用。定义一次(如
host_def),到处引用——改一处全生效。比如 uri_def 用一个正则严格限制 uri 格式,所有用到 uri 的地方共享这个约束。片段化让配置校验既严格又不重复。L05
插件的 schema
每个插件(apisix/plugins/*.lua)都定义自己的 schema(该插件接受哪些配置):
-- limit-count.lua 里
local schema = {
type = "object",
properties = {
count = {type = "integer", exclusiveMinimum = 0}, -- 限流次数 > 0
time_window = {type = "integer", exclusiveMinimum = 0}, -- 时间窗口 > 0
},
required = {"count", "time_window"}, -- 两个都必填
}
读法:插件自带 schema,让"配 limit-count 但漏填 count"这种错误在配置阶段就被拒。Day 11 会看到
plugin.check_schema 怎么用它。这套 schema 还能自动生成插件文档/前端表单(呼应上一站 Console 的动态表单)。L06
写入端校验:守住这道门
📝 建一条非法路由会立刻被拒
curl -X PUT .../apisix/admin/routes/1 -d '{"uri": 123}' # uri 应是字符串
# → 400 Bad Request: property "uri" validation failed: wrong type: expected string, got number校验放在写入端(Admin),不放读取端
因为 etcd 里的配置应该永远合法。守住写入这道门,读取时(请求处理)就不用再校验,省性能。好比"入库时质检合格,出库直接用"。所以坏配置进不了 etcd。Day 17 的 Admin API 会详讲。
写入时 check(schema, json) 守门:合法才进 etcd,非法直接 400;schema 片段复用喂给同一个校验函数
L07
编译缓存
jsonschema 库把 schema"编译"成 Lua 校验函数(比每次解释快)。APISIX 缓存编译结果,同一 schema 只编译一次。
读法:又是 APISIX "把重复计算缓存起来"的一贯风格(对比 Day 05 变量缓存、Day 06 路由预处理)。schema 校验虽主要在写入时,但插件配置变更、consumer 校验也用到,编译缓存避免重复开销。
L08
今日小结 + 动手
🧠 今天你应该能回答
- 为什么要在写入时校验配置?
- JSON Schema 是什么?为什么网关界都用它?
- schema 片段(host_def/uri_def)怎么体现 DRY?
- 校验为什么放在 Admin 写入端而非读取端?
✋ 动手
cd /Users/bitmart/work/codes/github/apisix
sed -n '59,90p' apisix/core/schema.lua
sed -n '50,93p' apisix/schema_def.lua
grep -n "schema" apisix/plugins/limit-count.lua | head
明天预告 · Day 10(第 2 周收官):请求最后要转发给后端——upstream 与 balancer:五种负载均衡算法怎么选实例、健康检查怎么剔除坏节点、失败怎么重试。