自定义 macro 必须在路由注册前完成;先调用 app.Macros().Int.RegisterFunc(...),再执行 app.Get() 或 party.Get(),否则已注册路由无法识别新宏,导致匹配失效。

自定义 macro 必须在路由注册前完成
注册宏不是“写完再用”,而是必须在任何 app.Get、app.Post 或 Party 调用之前执行,否则新路由根本不会识别你注册的 macro。Iris 在首次注册路由时就完成宏解析和正则编译,之后再注册的 macro 对已加载的路由无效。
常见错误现象:在 app.Get("/user/{id:int min(1)}", handler) 之后才调用 app.Macros().Int.RegisterFunc("min", ...),结果 /user/0 仍能匹配并进入 handler——因为该路由注册时 macro 还不存在,Iris 当作普通 {id:int} 处理了。
- 正确顺序:先
app.Macros().Int.RegisterFunc(...),再app.Get(...) - 推荐统一放在
main()开头、app := iris.New()之后立即注册 - 若用
Party分组,也要确保 macro 注册在party.Get之前,而非party.Use之后
macro 函数签名和返回值决定匹配逻辑
Iris 不关心你函数里怎么算,只看它返回的 func(string) bool 是否对当前参数值返回 false。只要返回 false,整个路由就不匹配(404),handler 根本不执行。
例如注册一个 max(100) 宏:
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
立即学习“go语言免费学习笔记(深入)”;
app.Macros().Int.RegisterFunc("max", func(limit int) func(string) bool {
return func(paramValue string) bool {
v, err := strconv.Atoi(paramValue)
if err != nil {
return false
}
return v <= limit
}
})
- 函数名
"max"会出现在路由中:/order/{oid:int max(100)} - 闭包捕获的
limit是你在路由里写的字面值(如100) - 内层函数接收的是原始字符串(如
"101"),必须自己转类型、做校验 - 返回
false→ Iris 直接跳过该路由,不进 handler,也不报错日志(静默不匹配)
不同参数类型对应不同 macro 注册入口
不能混用:int 类型的 macro 只能注册到 app.Macros().Int,string 的得去 .String,bool 的去 .Bool。Iris 按类型分隔 macro 命名空间,避免冲突,也防止类型误用。
-
{id:int min(1) max(999)}→ 全部走app.Macros().Int -
{name:string alphanumeric}→ 注册到app.Macros().String -
{active:bool required}→ 注册到app.Macros().Bool - 没注册的 macro 名(如
min未在.Int中注册),Iris 会忽略该约束,当作无此 macro 处理
macro 和内置类型配合使用才能真正拦截非法请求
仅靠 {id:int} 只能防住非数字(如 /user/abc → 404),但防不住业务非法值(如 /user/-5 或 /user/0)。macro 是唯一能在路由匹配阶段就过滤掉这些值的机制。
- 对比:在 handler 里写
if id → 请求已进业务层,浪费资源、暴露逻辑、绕过审计 - macro 方式:
/user/{id:int min(1)}→/user/0直接 404,不记录 access log,不触发中间件链,权限/审计模块完全无感知 - 多个 macro 可叠加:
{pid:int min(1) max(999999) odd},任意一个返回false即不匹配 - 注意:macro 不做自动解码,
{path:path}传入的仍是 URL 编码字符串,macro 函数里需手动url.PathUnescape再校验
macro 的真正价值不在“能写”,而在“必须提前注册 + 类型隔离 + 匹配即拦截”这三点。漏掉任一环,就退化成运行时 if 判断,失去路由层语义控制能力。


















