我在使用大猩猩/多路复用器实现轻微的MVC设计时遇到一些问题。

模块的布局如下:

main.go
-- controllers
---- base.controller.go
---- example.controller.go
-- models
---- base.model.go
---- example.controller.go
controllers中的所有文件都在controllers包中,与models相同,然后main.gomain包。

目前,我只是想让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.")
    }
}

最佳答案

大猩猩mux.Router应该用于在一组预定义规则(例如主机,路径,协议,方案等)与其处理程序(http.Handlerhttp.HandlerFunc)之间创建映射。大猩猩多路复用器可以用来代替标准服务器多路复用器。如果您将gorilla/mux与内置的http服务器mux结合起来作为原始问题,即

func main () {
    http.Handle("/v1", controllers.V1Router)
    if err := http.ListenAndServe(":8000", nil); err != nil {
        log.Fatal("Serving error.")
    }
}

客户端访问/v1controllers.V1Router时实际发生的情况将通过将请求路径/v1传递给V1Router1来调用。在controllers.V1Router中,您定义了/将由BaseHandler处理。但是,由于传入的请求路径是/v1,因此它与您的路由表不匹配。如果要定义子路由,可以执行以下操作(这是我在第一句话中的意思):
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...
}

关于go - 跨软件包共享 gorilla /多路复用器路由器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44388292/

10-17 00:00