iris 不支持连续可选参数,因其 radix tree 路由依赖明确分隔边界,/users/123 与 /users/123/john 无法唯一区分;推荐用 {path:path} 通配后手动解析,或显式定义多条具体路由。

Iris 的路由引擎本身不支持“多个可选参数”语法(比如 /users/{id:int?}/{name:string?}),这种写法会直接报错或无法匹配。
为什么 Iris 不允许连续可选参数
Iris 使用 radix tree 路由,其路径解析依赖明确的分隔边界。当两个参数都标为可选时,/users/123 和 /users/123/john 在树结构中无法被唯一区分——引擎无法判断 john 是第二个参数的值,还是第三个静态段的开始。这不是 bug,而是设计取舍:优先保证匹配确定性与性能。
替代方案:用单个通配符 + 手动解析
对真正需要灵活路径的场景(如管理后台的嵌套资源),推荐用 {path:path} 捕获剩余路径,再在 handler 中拆解:
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
app.Get("/users/{path:path}", func(ctx iris.Context) {
path := ctx.Params().GetStringDefault("path", "")
parts := strings.Split(path, "/")
switch len(parts) {
case 0:
// /users → 列表
case 1:
// /users/123 → 单个用户
id, _ := strconv.Atoi(parts[0])
ctx.JSON(iris.Map{"id": id})
case 2:
// /users/123/profile → 用户子资源
id, _ := strconv.Atoi(parts[0])
sub := parts[1]
ctx.JSON(iris.Map{"id": id, "sub": sub})
default:
ctx.StatusCode(404)
}
})
- 必须把
{path:path}放在最后,否则会覆盖其他更具体的路由 -
path类型是特殊标记,表示“捕获从该位置到路径末尾的所有内容”,不能与其他命名参数混用 - 注意手动校验
parts长度和内容,避免 panic
更安全的做法:定义多条明确路由
如果可选组合有限(比如只有 3 种路径形态),显式声明比通配更可靠、更易调试:
app.Get("/users", listUsers)
app.Get("/users/{id:int}", getUserByID)
app.Get("/users/{id:int}/profile", getUserProfile)
app.Get("/users/{id:int}/settings", getUserSettings)
- 每条路由独立注册,匹配优先级按注册顺序(先注册的更靠前)
- 避免参数类型冲突:
{id:string}和{id:int}不能共存于同一前缀下,否则编译期报错 - 中间件作用域也按路由粒度生效,便于做细粒度权限控制
真正容易被忽略的是:Iris 的路由匹配发生在请求进入 handler 前,一旦进来了,ctx.Params() 就固定了——所以别指望在中间件里动态改参数名或补默认值。路径设计阶段就要想清楚哪些是必需语义,哪些只是 UI 层的便利跳转。










