如何使用http.ServeMux实现路由分组?
问题原因
你遇到的404错误,核心是ServeMux的路径匹配规则和路由转发逻辑没处理对:
- 当你用
apiMux.Handle("/my-group", group)时,只有请求路径完全等于/my-group的请求才会被转发给子ServeMux; - 即使把挂载路径改成
/my-group/,子ServeMux会收到完整的请求路径(比如/my-group/foo),但你子路由注册的是/foo,自然匹配不上。
正确实现方式
方式一:用http.StripPrefix剥离前缀(推荐)
这种方式能真正实现路由分组,统一管理前缀,子路由只需写相对路径:
import "net/http" func GetAPI() *http.ServeMux { apiMux := http.NewServeMux() group := http.NewServeMux() // 子路由写相对路径 group.HandleFunc("/foo", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("Success from /my-group/foo")) }) // 剥离"/my-group/"前缀后,将剩余路径传给子ServeMux apiMux.Handle("/my-group/", http.StripPrefix("/my-group/", group)) // 其他全局路由示例 apiMux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("Healthy")) }) return apiMux }
此时访问http://localhost:8080/my-group/foo就能正常匹配到子路由。
方式二:子路由统一带前缀(不推荐,维护性差)
如果不想用StripPrefix,可以给子路由直接加上分组前缀,再挂载到父ServeMux:
import "net/http" func GetAPI() *http.ServeMux { apiMux := http.NewServeMux() group := http.NewServeMux() // 子路由直接写完整分组路径 group.HandleFunc("/my-group/foo", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("Success from /my-group/foo")) }) apiMux.Handle("/", group) // 其他全局路由 apiMux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("Healthy")) }) return apiMux }
关键规则提醒
ServeMux挂载路径如果以/结尾,会匹配所有以此路径开头的请求;否则仅匹配完全相等的路径。- 子
ServeMux默认会收到完整请求路径,必须用StripPrefix剥离前缀,才能让子路由匹配相对路径。
内容的提问来源于stack exchange,提问作者baitendbidz
相关产品推荐
相关产品推荐

