静态路径优先于参数路径匹配,Echo路由树按static→param→any三级固化优先级排序,与注册顺序无关;高频端点须用纯静态路径,避免参数化;/*通配符退化为线性遍历,应慎用;多层参数增加解析开销,宜收敛资源名或改用header传参;Group仅加前缀不改变优先级。

静态路径永远比参数路径先匹配
Echo 的路由树在插入时就按 Static → Param → Match any 三级固化优先级,和你代码里注册的顺序无关。比如同时注册了 /users/new 和 /users/:id,哪怕后者先写,/users/new 仍会命中——因为它的节点类型是 skind(static kind),而前者是 pkind(param kind),底层比较时直接按 kind 值排序。
常见错误现象:接口返回 404 或意外走到 :id 处理器,其实只是因为你写了 /health 却被 /:service/health 拦截了。
- 高频健康检查、指标端点必须用纯静态路径,如
/health、/metrics - 避免把静态路径“参数化”来图省事,比如用
/:env/api/status代替/api/status - 调试时可打印
e.Routes().Routes()查看当前所有注册路由的原始顺序和类型
/* 通配符会退化为线性遍历
/* 对应的 akind(any kind)节点不参与 Trie 树的前缀匹配,每次请求都得从头遍历所有 akind 路由。它只在其他两级都失败后才兜底触发,但本身匹配开销大。
使用场景有限:通常只用于前端 SPA 的 404 页面兜底,或极少数需要捕获任意子路径的代理逻辑。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 别用
/api/*代替/api/v1/users+/api/v1/posts等具体路径 - 如果真要支持多层动态路径,优先拆成
/api/v1/:resource/:id,而非/api/v1/* - 注意
/*会吃掉所有子路径,包括你后来加的/api/v2/xxx,除非显式提前注册
嵌套参数越多,参数提取开销越大
每层 :param 都要执行一次字符串切分 + map 插入。像 /v1/:tenant/:project/:resource/:id 这种四层参数路径,比单层 /v1/users/:id 多出近 3 倍解析耗时(实测 10k RPS 下高约 0.3ms)。
这不是路由匹配慢,而是匹配成功后的上下文初始化成本。
- 业务上能收敛到固定资源名的,就别参数化,例如
/v1/users/:id比/v1/:resource/:id更快更安全 - 需要多租户隔离的,优先用 header 或 cookie 传
tenant_id,而非塞进 URL - 如果必须多层参数,确保最左段尽可能静态,比如
/v1/admin/:id优于/v1/:role/:id
Group 前缀不影响路由优先级判断
e.Group("/admin") 只是给内部路由自动加前缀,并不改变其节点类型或插入位置。生成的 /admin/users/new 仍是 skind,/admin/users/:id 仍是 pkind,优先级规则照旧。
容易踩的坑:以为 “group 内的路由天然更高优”,结果在 group 里注册了 /*,反而把根路径下更具体的 /health 给屏蔽了。
- Group 是组织手段,不是调度机制;优先级只看最终展开的完整路径形态
- 跨 group 的同级路径(如
/health和/admin/health)互不影响,各自独立参与匹配 - 若需强制某条路由优先,唯一可靠方式是让它成为更具体的静态路径,而不是依赖 group 层级
:id 和一个 /health 放反了,就能让 P99 延迟多出 0.5ms——这在 20ms 级接口里已经不可忽视。


















