通配符路由必须写为 /path/* 才能匹配子路径,如 /users/* 可捕获 /users/123、/users/export?format=csv 等,但不匹配 /user 或 /users2;c.Param("*") 返回去除前缀后的相对路径,不含开头斜杠和查询参数。

通配符路由必须用 /path/*,不能只写 /path
Echo 的通配符路由不是模糊匹配,而是明确要求路径末尾带 /* 才能捕获子路径。比如想代理 /users/123、/users/export?format=csv 这类请求,注册 e.Any("/users", ...) 是无效的——它只匹配字面量 /users,不匹配任何子路径。
正确写法是:e.Any("/users/*", handler)。这个 * 是占位符,表示“匹配该前缀下的所有路径”,包括带查询参数、带路径分段、甚至空路径(如 /users/)。
-
/users/*匹配/users、/users/、/users/123、/users/roles/admin?tab=perms -
/api/v1/*匹配/api/v1/、/api/v1/users、/api/v1/products/42/reviews - 但
/users/*不匹配/user或/users2—— 前缀必须严格一致
/* 会吃掉整个子路径,c.Param("*") 就是你要的原始路径段
注册 /users/* 后,Echo 会把 * 对应的部分作为特殊参数注入上下文,名称就是 "*"。你不需要手动截断或拼接,直接取值即可:
e.GET("/files/*", func(c echo.Context) error {
subpath := c.Param("*") // 比如请求 /files/docs/report.pdf → subpath == "docs/report.pdf"
return c.String(http.StatusOK, "Serving: "+subpath)
})
注意:c.Param("*") 返回的是去除前缀后的相对路径,不含开头斜杠,也不含查询参数。如果需要完整 URL 路径(含查询),用 c.Request().URL.Path 和 c.Request().URL.RawQuery 拼接。
通配符和参数路由冲突时,Echo 优先级是:静态 > 参数 > 通配符
如果你同时注册了 /users/:id 和 /users/*,Echo 会按「最长精确匹配」原则处理,不会让通配符抢走参数路由的请求。也就是说:
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
-
GET /users/123→ 匹配/users/:id,c.Param("id") == "123" -
GET /users/export→ 匹配/users/*,c.Param("*") == "export" -
GET /users/→ 匹配/users/*,c.Param("*") == ""
但反过来,如果先注册 /users/*,再注册 /users/123(静态),那 /users/123 会被优先命中——因为静态路由优先级高于通配符。顺序本身不影响匹配逻辑,但 Echo 内部是按树结构组织的,不是线性遍历。
反向代理场景下,/* 路由必须配合自定义 Director
直接用 httputil.NewSingleHostReverseProxy + /users/* 会出问题:默认行为会把原始请求路径(如 /users/123)原样转发给后端,而你的后端可能只监听 /123 或 /api/123。这时候必须重写 Director:
usersProxy := httputil.NewSingleHostReverseProxy(usersURL)
usersProxy.Director = func(req *http.Request) {
req.URL.Scheme = usersURL.Scheme
req.URL.Host = usersURL.Host
// 把 /users/xxx → /xxx
req.URL.Path = strings.TrimPrefix(req.URL.Path, "/users")
// 可选:补回开头斜杠(如果后端要求)
if req.URL.Path != "" && !strings.HasPrefix(req.URL.Path, "/") {
req.URL.Path = "/" + req.URL.Path
}
}
e.Any("/users/*", echo.WrapHandler(usersProxy))
漏掉这一步,90% 的代理请求会 404——尤其是当后端服务没做路径前缀适配时。










