Iris路由匹配基于radix tree结构,字面量路径(如/user/admin)优先级高于泛匹配路径(如/user/{id:int}),因前者为完整前缀、后者为深层通配节点;类型约束(如{id:int})参与正则生成并影响匹配成败,未加约束默认string导致过度匹配。

路由匹配发生在请求进入 handler 之前,由 radix tree + 正则引擎共同决定是否命中;顺序、锚点、类型标注缺一不可,否则看似匹配的路径可能被跳过或误判。
radix tree 匹配优先级怎么影响路由选择
Iris 的路由树不是按代码顺序线性扫描的,而是基于路径结构构建的前缀树。/user/{id:int} 和 /user/admin 这两个路由,后者会优先生效——因为 /user/admin 是完整字面量路径,而 /user/{id:int} 是带通配符的泛匹配节点,树中位置更深、优先级更低。
常见错误现象:注册了 app.Get("/user/{id}", ...) 后,再注册 app.Get("/user/admin", ...) 却发现访问 /user/admin 仍进到第一个 handler。这是因为没加类型约束,{id} 默认是 string 类型,匹配太宽,把 admin 也吞掉了。
解决办法只有两个:
- 给泛匹配加约束,比如改用
/user/{id:int}或/user/{id:string regexp:^[0-9a-z-]+$},让admin不满足条件 - 确保字面量路由注册在泛匹配之前(虽然不推荐依赖顺序,但这是唯一能绕过树结构的方式)
- 用
app.Subdomain("admin").Get("/user", ...)拆到不同子域 Party,彻底隔离匹配空间
{param:type} 中的 type 约束到底起什么作用
类型标注不是装饰,它直接参与匹配阶段的正则生成和转换逻辑。例如 {id:int} 等价于 {id:string regexp:^-?[0-9]+$},而 {name:string regexp:^(?!admin$).+$} 必须显式写 string 才能启用正则解析。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
关键点:
- 不写类型标注(如
{id})→ Iris 当作string处理,不做任何格式校验,空字符串、特殊字符全收 - 写了
{id:int}→ 请求路径必须是纯数字,否则整个路由不匹配,直接 404(不是 400) -
{id:int min(1)}这类 macro 语法是 Iris v12.2+ 新增的,它会在匹配后额外做数值范围检查,失败时仍进 handler,但ctx.Params().GetIntDefault("id", 0)返回默认值 - 所有正则必须带
$锚定结尾,否则/user/admi也会匹配/user/{name:string regexp:^(?!admin$).*$}
为什么 /user/ 和 /user 都能访问,但行为不一致
这是 DisablePathCorrection 全局开关导致的路径标准化行为。默认为 false,Iris 会自动对尾部斜杠做 301 重定向:访问 /user/ → 重定向到 /user;反之亦然(取决于路由注册形式)。
问题在于这个开关无法 per-route 控制。如果你注册了 app.Get("/user", ...),又希望 /user/ 也能进同一个 handler,不能靠配置开关,得手动处理:
- 注册两个路由:
app.Get("/user", h)和app.Get("/user/", h) - 或者用中间件统一截断尾部斜杠:
strings.TrimSuffix(ctx.Request().URL.Path, "/"),再调用ctx.Request().URL.Path = cleanPath(注意要放在其他中间件之前) - 别试图用
app.Get("/user{slash:/?}")—— Iris 不支持这种可选段写法
正则约束里最容易踩的三个坑
正则写错不会报编译错误,但会导致路由静默失效或误匹配,调试极难。
- 漏掉
^和$:写成regexp:(?!admin)允许/user/admins和/user/xadmin,正确写法是regexp:^(?!admin$|root$).+$ - 贪婪匹配导致空字符串:用
.*而不是.+,结果/user/(空 name)也被接受,而业务上通常不允许 - 竖线
|周围加空格:admin$ | root$会被当作文本字面量,正则引擎实际匹配的是admin$ | root$这个字符串,而不是“admin 或 root”
复杂关键字排除建议直接用白名单中间件替代正则,尤其是当需要查数据库判断用户名是否存在时——路由层只负责结构合法性,语义合法性交给 handler 或专用中间件更可控。


















