动态路由注册必须用app.Party分组管理,直接根路由调用Get/Post仅为静态注册;真正支持运行时增删的是基于Party的子路由组,配合group.Reset()可安全重载,且宏语法{id:int min(1)}须注册时完整写死,不可运行时拼接。

动态路由注册必须用 app.Party 分组管理
直接在根 app 上反复调用 Get/Post 不算“动态加载”,只是静态注册。真正支持运行时增删的,是基于 Party 的子路由组。Iris 的 Party 本质是一个可挂载、可卸载的路由容器,配合 iris.Application.RegisterView 或自定义中间件,才能实现配置驱动的动态加载逻辑。
常见错误是把路由字符串拼接后直接 app.Get(routeStr, handler) —— 这看似“动态”,但无法统一卸载、无权限上下文、不参与 iris-admin 的 permRoutes 管理,后续删路由时只能靠全局 map 手动追踪,极易漏删或 panic。
- 正确做法:先
group := app.Party("/api"),再对group注册所有子路由 - 若需热更新,应保存该
group引用,后续调用group.Reset()清空全部子路由,再重新注册新规则 -
group.Reset()不影响父级路由,也不会触发 GC 泄漏,是 iris 内置的安全重载方式
{id:int min(1)} 这类宏语法必须在注册时解析,不能运行时替换
很多人误以为可以把 "/user/{id}" 存进数据库,再用 strings.Replace 拼出 "/user/{id:int min(1)}",然后传给 app.Get —— 这会失败,因为 Iris 的 macro 解析发生在路由编译阶段,不是字符串模板渲染。
宏类型(如 int、min)对应的是预编译的正则和类型转换函数,必须在 app.Get 调用时就完整写死。运行时拼接的字符串会被当作纯 string 类型处理,ctx.Params().GetIntDefault("id", 0) 将始终返回 0,且不会校验数字范围。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 正确做法:从配置或 DB 读取带完整 macro 的路径字符串,例如
"/users/{id:int max(9999)}",原样传入group.Get - 若需参数约束可变,应提前注册自定义 macro 函数,比如
app.Macros().Int.RegisterFunc("range", rangeValidator) - macro 函数注册必须在任何路由注册前完成,否则新注册的路由无法识别该 macro
iris-admin 的 permRoutes 是动态权限路由的核心载体
单纯用 Party.Reset() 只能清空路由,但权限控制、日志记录、审计追踪这些企业级能力,得依赖 iris-admin 的 permRoutes 结构。它内部维护了路由路径、HTTP 方法、角色白名单、中间件链等元数据,删除时会自动触发 log.Printf("iris-admin: delete %d router\n", len(dels))。
绕过 iris-admin 直接操作底层 Party,会导致权限系统脱节:前端菜单可能还显示按钮,但点击后 403;或者日志里查不到某条路由的变更记录。
- 加载时:调用
ws.AddRoute(method, path, handler, roles...),而非group.Get - 卸载时:用
ws.DeleteRoute(path, method),它会同步清理内存中的permRoutes和关联中间件 - 权限中间件必须通过
ws.UseRouter(...)注入,不能手动app.Use(...),否则不参与权限校验流
动态加载后 Context 生命周期不受影响,但中间件顺序很关键
有人担心动态加载路由会导致已存在的请求 Context 对象被污染或复用异常。实际上 Iris 的 Context 来自对象池,每次请求都新建,与路由注册时机无关。真正容易出问题的是中间件执行顺序。
比如你为 /admin/* 组添加了鉴权中间件,又在动态加载时为其中某个子路径 /admin/export 单独加了限流中间件,但没指定 Before 或 After 位置——Iris 默认追加到末尾,可能导致限流在鉴权之前执行,未登录用户也能触发限流计数。
- 务必使用
group.UseRouter(middleware1, middleware2)显式声明顺序,不要依赖隐式叠加 - 动态加载的路由若需特殊中间件,应在
ws.AddRoute时通过第 4 个参数传入,而不是事后group.Use - 所有中间件函数必须是并发安全的,尤其涉及共享计数器(如限流)时,避免用
map+sync.Mutex手写,优先用golang.org/x/sync/semaphore
permRoutes 的生命周期绑定。这两点一旦错位,表面路由能访问,背后权限或参数校验就静默失效,排查起来要翻好几层源码。


















