【发布时间】:2017-11-07 08:51:37
【问题描述】:
我在使用 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 假假假}) %!!(MISSING)s(http.HandlerFunc=0xc8df0) [%!!(MISSING)s(*mux.routeRegexp=&{/ 假假真假 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中访问它,并且在其他控制器中创建子路由器。
我对@987654334@ 还很陌生,但我正在努力学习最佳实践!任何帮助将不胜感激!
示例代码如下:
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.")
}
}
针对cmets,我尝试了这个解决方案,结果相同:
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.")
}
}
【问题讨论】:
-
您不能混合使用标准多路复用器 (
http.DefaultServerMux) 和gorilla/mux。如果您不想替换标准参数,则应将gorilla router作为http.ListenAndServe的第二个参数传递。你的控制器的路径是什么样子的? -
@putu 我现在所做的是在
main package中添加了一个默认的r := mux.NewRouter(),并将/v1/处理为controllers.V1Router(),我得到了一个零指针错误。我确实添加了r来替换ListenAndServe中的nil。 -
@putu 好的,那是我的错误 - 我在调试时出错。以原来的方式修复所有内容我得到了同样的错误。
-
我的第一条评论可能不是 100% 正确的。您可以混合使用它,但只有通过
http.Handle("/", controllers.V1Router)注册它或将其作为http.ListenAndServe的第二个参数传递它才有效。/v1的子路由器必须使用Route.Subrouter创建,例如v1 := V1Router.PathPrefix("/v1").Subrouter(),然后将基本控制器注册到v1。 -
@putu,您评论的第一部分 - 这与我第一次尝试的解决方案不同吗?