跨包共享 gorilla/mux 路由器
Sharing a gorilla/mux router across packages
我在使用 gorilla/mux 实现轻微的 MVC 设计时遇到了一些问题。
模块布局如下:
main.go
-- controllers
---- base.controller.go
---- example.controller.go
-- models
---- base.model.go
---- example.controller.go
controllers
中的所有文件都在controllers
包中,与models
相同,然后main.go
是main
包。
目前我只是想让 Base Controller
能够与正在工作的 main package
共享,尽管它在尝试实现路由时会抛出一些错误。构建没有抛出任何错误,但路由不可用。如果我在 Gorilla/Mux 文档中实现 Walk
函数来打印出 mux.Router
的所有注册路由,那么它会给我这个错误:
&{%!!(MISSING)s(*mux.Router=&{ [0xc4200901b0] map[] true
false false false}) %!!(MISSING)s(http.HandlerFunc=0xc8df0)
[%!!(MISSING)s(*mux.routeRegexp=&{/ false false true false
0xc420095360 / [] []})] %!!(MISSING)s(*mux.routeRegexpGroup=&{
0xc420016240 []}) %!!(MISSING)s(bool=true) %!!(MISSING)s(bool=false)
%!!(MISSING)s(bool=false) %!!(MISSING)s(bool=false)
%!!(MISSING)s(mux.BuildVarsFunc=)}
全局var V1Router *mux.Router
的原因首先是在main package
中访问它,并在其他控制器中创建子路由器。
我是 Go
的新手,但我正在尽最大努力学习最佳实践!任何帮助将不胜感激!
示例代码如下:
base.controllers.go
package controllers
import (
"fmt"
"bytes"
"net/http"
"github.com/gorilla/mux"
)
var V1Router *mux.Router
func init () {
V1Router = mux.NewRouter()
V1Router.StrictSlash(true)
V1Router.HandleFunc("/", BaseHandler)
}
// Base route to access the API Documentation.
func BaseHandler (w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello, Gophers!")
}
main.go
package main
import (
"net/http"
"log"
"github.com/projectrepo/project/models"
"github.com/projectrepo/project/controllers"
"github.com/gorilla/mux"
)
func main () {
http.Handle("/v1", controllers.V1Router)
if err := http.ListenAndServe(":8000", nil); err != nil {
log.Fatal("Serving error.")
}
}
针对评论,我尝试了这个解决方案,结果相同:
package main
import (
"net/http"
"log"
"github.com/projectrepo/project/models"
"github.com/projectrepo/project/controllers"
"github.com/gorilla/mux"
)
func main () {
r := mux.NewRouter()
r.Handle("/v1", controllers.V1Router)
if err := http.ListenAndServe(":8000", r); err != nil {
log.Fatal("Serving error.")
}
}
Gorilla mux.Router
应该用于在一组预定义规则(例如主机、路径、协议、方案等)和它的处理程序(http.Handler
或http.HandlerFunc
)。 Gorilla mux 可用于替换标准服务器 mux。如果您将 gorilla/mux
与内置的 http 服务器 mux 结合起来作为您的原始问题,即
func main () {
http.Handle("/v1", controllers.V1Router)
if err := http.ListenAndServe(":8000", nil); err != nil {
log.Fatal("Serving error.")
}
}
当客户端访问 /v1
为 controllers.V1Router
时实际发生的情况将被调用,请求路径 /v1
传递给 V1Router1
。在 controllers.V1Router
中,您定义 /
将由 BaseHandler
处理。但是,由于传入请求路径是 /v1
,它不会与您的路由匹配 table。如果你想定义子路由,你可以这样做(这是我在第一条评论中的意思):
func main () {
r := mux.NewRouter()
v1 := r.PathPrefix("/v1").Subrouter()
controllers.RegisterHandlers(v1)
if err := http.ListenAndServe(":8000", r); err != nil {
log.Fatal("Serving error.")
}
}
然后在控制器(base.controllers.go
)中定义
//Register handlers and it's sub router
func RegisterHandlers(r *mux.Router) {
//base handler, i.e. /v1
r.StrictSlash(true)
r.HandleFunc("/", BaseHandler)
//example sub-router, i.e. /v1/example
ex := r.PathPrefix("/example").Subrouter()
ex.HandleFunc("/", ExampleHandler)
//other handlers...
}
我在使用 gorilla/mux 实现轻微的 MVC 设计时遇到了一些问题。
模块布局如下:
main.go
-- controllers
---- base.controller.go
---- example.controller.go
-- models
---- base.model.go
---- example.controller.go
controllers
中的所有文件都在controllers
包中,与models
相同,然后main.go
是main
包。
目前我只是想让 Base Controller
能够与正在工作的 main package
共享,尽管它在尝试实现路由时会抛出一些错误。构建没有抛出任何错误,但路由不可用。如果我在 Gorilla/Mux 文档中实现 Walk
函数来打印出 mux.Router
的所有注册路由,那么它会给我这个错误:
&{%!!(MISSING)s(*mux.Router=&{ [0xc4200901b0] map[] true false false false}) %!!(MISSING)s(http.HandlerFunc=0xc8df0) [%!!(MISSING)s(*mux.routeRegexp=&{/ false false true false 0xc420095360 / [] []})] %!!(MISSING)s(*mux.routeRegexpGroup=&{ 0xc420016240 []}) %!!(MISSING)s(bool=true) %!!(MISSING)s(bool=false) %!!(MISSING)s(bool=false) %!!(MISSING)s(bool=false) %!!(MISSING)s(mux.BuildVarsFunc=)}
全局var V1Router *mux.Router
的原因首先是在main package
中访问它,并在其他控制器中创建子路由器。
我是 Go
的新手,但我正在尽最大努力学习最佳实践!任何帮助将不胜感激!
示例代码如下:
base.controllers.go
package controllers
import (
"fmt"
"bytes"
"net/http"
"github.com/gorilla/mux"
)
var V1Router *mux.Router
func init () {
V1Router = mux.NewRouter()
V1Router.StrictSlash(true)
V1Router.HandleFunc("/", BaseHandler)
}
// Base route to access the API Documentation.
func BaseHandler (w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello, Gophers!")
}
main.go
package main
import (
"net/http"
"log"
"github.com/projectrepo/project/models"
"github.com/projectrepo/project/controllers"
"github.com/gorilla/mux"
)
func main () {
http.Handle("/v1", controllers.V1Router)
if err := http.ListenAndServe(":8000", nil); err != nil {
log.Fatal("Serving error.")
}
}
针对评论,我尝试了这个解决方案,结果相同:
package main
import (
"net/http"
"log"
"github.com/projectrepo/project/models"
"github.com/projectrepo/project/controllers"
"github.com/gorilla/mux"
)
func main () {
r := mux.NewRouter()
r.Handle("/v1", controllers.V1Router)
if err := http.ListenAndServe(":8000", r); err != nil {
log.Fatal("Serving error.")
}
}
Gorilla mux.Router
应该用于在一组预定义规则(例如主机、路径、协议、方案等)和它的处理程序(http.Handler
或http.HandlerFunc
)。 Gorilla mux 可用于替换标准服务器 mux。如果您将 gorilla/mux
与内置的 http 服务器 mux 结合起来作为您的原始问题,即
func main () {
http.Handle("/v1", controllers.V1Router)
if err := http.ListenAndServe(":8000", nil); err != nil {
log.Fatal("Serving error.")
}
}
当客户端访问 /v1
为 controllers.V1Router
时实际发生的情况将被调用,请求路径 /v1
传递给 V1Router1
。在 controllers.V1Router
中,您定义 /
将由 BaseHandler
处理。但是,由于传入请求路径是 /v1
,它不会与您的路由匹配 table。如果你想定义子路由,你可以这样做(这是我在第一条评论中的意思):
func main () {
r := mux.NewRouter()
v1 := r.PathPrefix("/v1").Subrouter()
controllers.RegisterHandlers(v1)
if err := http.ListenAndServe(":8000", r); err != nil {
log.Fatal("Serving error.")
}
}
然后在控制器(base.controllers.go
)中定义
//Register handlers and it's sub router
func RegisterHandlers(r *mux.Router) {
//base handler, i.e. /v1
r.StrictSlash(true)
r.HandleFunc("/", BaseHandler)
//example sub-router, i.e. /v1/example
ex := r.PathPrefix("/example").Subrouter()
ex.HandleFunc("/", ExampleHandler)
//other handlers...
}