gorilla/mux 嵌套路由不匹配
gorilla/mux nested routes not matching
我不确定为什么我的路线没有被匹配。 localhost:8000
匹配,我得到了预期的输出但不是 localhost:8000/admin/test
。当我尝试在浏览器上匹配 /admin/test
时,我得到 404
。
我想以这种方式组织我的代码,因为我想在每个 package
.
中包含路由和其他子路由
项目结构
/admin
admin.go
main.go
main.go
package main
import (
"example.com/liondancer/playground/admin"
"fmt"
"github.com/gorilla/mux"
"log"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hi there!")
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/", handler)
r.PathPrefix("/admin").Handler(admin.NewHandler())
log.Fatal(http.ListenAndServe(":8000", r))
}
admin.go
package admin
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
type Handler struct {
router *mux.Router
}
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.router.ServeHTTP(w, r)
}
func NewHandler() *Handler {
h := &Handler{}
r := mux.NewRouter()
h.router = r
h.addRoutes()
return h
}
func (h *Handler) addRoutes() {
fmt.Print("hi here"). // <--- printed here to prove func gets ran.
h.router.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "test")
})
}
我能够使用 Subrouter()
运行 这段代码。
这是 link 和 Subrouter()
用法示例
func main() {
r := mux.NewRouter()
r.HandleFunc("/", handler)
r.PathPrefix("/admin").Subrouter().HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "test")
})
log.Fatal(http.ListenAndServe(":8000", r))
}
如果你想将它分离到另一个文件中,你也可以这样做:
func main() {
r := mux.NewRouter()
r.HandleFunc("/", handler)
subRoute := r.PathPrefix("/admin").Subrouter()
NewHandler(subRoute)
log.Fatal(http.ListenAndServe(":8000", r))
}
func NewHandler(r* mux.Router) *Handler {
h := &Handler{}
h.router = r
h.AddRoutes()
return h
}
func (h *Handler) AddRoutes() {
fmt.Print("hi here") // <--- printed here to prove func gets ran.
h.router.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "test")
})
}
您的嵌套处理程序永远不会匹配,因为您没有删除早期处理程序的 URL 前缀。
显示我的意思的快速修复:
// h.router.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
// quick fix
h.router.HandleFunc("/admin/test", func(w http.ResponseWriter, r *http.Request) {
显然你希望你的嵌套处理程序不知道它是如何嵌套的,所以在注册子处理程序时,去除 URL 前缀,这样你的子处理程序将匹配:
// r.PathPrefix("/admin").Handler(admin.NewHandler())
// better
r.PathPrefix("/admin/").Handler(
http.StripPrefix(
"/admin",
admin.NewHandler(),
),
)
我不确定为什么我的路线没有被匹配。 localhost:8000
匹配,我得到了预期的输出但不是 localhost:8000/admin/test
。当我尝试在浏览器上匹配 /admin/test
时,我得到 404
。
我想以这种方式组织我的代码,因为我想在每个 package
.
项目结构
/admin
admin.go
main.go
main.go
package main
import (
"example.com/liondancer/playground/admin"
"fmt"
"github.com/gorilla/mux"
"log"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hi there!")
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/", handler)
r.PathPrefix("/admin").Handler(admin.NewHandler())
log.Fatal(http.ListenAndServe(":8000", r))
}
admin.go
package admin
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
type Handler struct {
router *mux.Router
}
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.router.ServeHTTP(w, r)
}
func NewHandler() *Handler {
h := &Handler{}
r := mux.NewRouter()
h.router = r
h.addRoutes()
return h
}
func (h *Handler) addRoutes() {
fmt.Print("hi here"). // <--- printed here to prove func gets ran.
h.router.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "test")
})
}
我能够使用 Subrouter()
运行 这段代码。
这是 link 和 Subrouter()
用法示例
func main() {
r := mux.NewRouter()
r.HandleFunc("/", handler)
r.PathPrefix("/admin").Subrouter().HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "test")
})
log.Fatal(http.ListenAndServe(":8000", r))
}
如果你想将它分离到另一个文件中,你也可以这样做:
func main() {
r := mux.NewRouter()
r.HandleFunc("/", handler)
subRoute := r.PathPrefix("/admin").Subrouter()
NewHandler(subRoute)
log.Fatal(http.ListenAndServe(":8000", r))
}
func NewHandler(r* mux.Router) *Handler {
h := &Handler{}
h.router = r
h.AddRoutes()
return h
}
func (h *Handler) AddRoutes() {
fmt.Print("hi here") // <--- printed here to prove func gets ran.
h.router.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "test")
})
}
您的嵌套处理程序永远不会匹配,因为您没有删除早期处理程序的 URL 前缀。 显示我的意思的快速修复:
// h.router.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
// quick fix
h.router.HandleFunc("/admin/test", func(w http.ResponseWriter, r *http.Request) {
显然你希望你的嵌套处理程序不知道它是如何嵌套的,所以在注册子处理程序时,去除 URL 前缀,这样你的子处理程序将匹配:
// r.PathPrefix("/admin").Handler(admin.NewHandler())
// better
r.PathPrefix("/admin/").Handler(
http.StripPrefix(
"/admin",
admin.NewHandler(),
),
)