【问题标题】:How do I split URLS in multiple Files using gorilla/mux?如何使用 gorilla/mux 在多个文件中拆分 URL?
【发布时间】:2013-10-21 19:19:25
【问题描述】:

我的目录结构如下:

myapp/
|
+-- moduleX
|      |
|      +-- views.go
|
+-- start.go

应用程序从start.go 开始,然后我从那里配置所有路由并从moduleX/views.go 导入处理程序,如下所示:

package main

import (
    "net/http"
    "github.com/gorilla/mux"
    "myapp/moduleX"
)

func main() {
    r := mux.NewRouter()
    http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./templates/static/"))))
    r.HandleFunc("/", moduleX.SomePostHandler).Methods("POST")
    r.HandleFunc("/", moduleX.SomeHandler)
    http.Handle("/", r)
    http.ListenAndServe(":8080", nil)
}

现在我想添加更多模块并问自己是否(以及如何)可以在urls.go 文件中定义模块中的url,并以某种方式将它们“导入”到start.go。具体来说,我希望start.go 只需一个导入或某种module.GetURLs 函数即可知道所有somemodule/urls.go 文件中的所有URL。

【问题讨论】:

    标签: url go mux


    【解决方案1】:

    为什么不让处理程序将自己插入到路由表中?

    如果您在自己的 go 文件中定义每个处理程序,请为每个文件使用 `init()` 函数将处理程序添加到全局路由表中

    比如:


    main.go:

    type route{
        method string
        path string
        handler func(w http.ResponseWriter, r *http.Request)
    }
    var routes = make([]route,0)
    
    func registerRoute(r route){
        routes = append(routes,r)
    }
    
    func server(){
        r := mux.NewRouter()
        http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./templates/static/"))))
        // set up all the registered routes
        for _, rt = range(routes){
            r.HandleFunc(rt.path,rt.handler).Methods(rt.Method)
        }
        // and there's usually some other stuff that needs to go in here
    
        //before we finally serve the content here!
        http.ListenAndServe(":8080", nil)
    }
    

    你的模块.go:

    func init(){
        r = route{
            method="GET",
            path="/yourmodule/path/whatever",
            handler=yourHandlerFunc,
        }
        registerRoute(r)
    }
    
    func yourHandlerFunc(w http.ResponseWriter, r *http.Request){
        //awesome web stuff goes here
    }
    

    在执行包 main() 之前,会为包中的每个文件调用 init(),因此您可以确保在启动服务器之前注册所有处理程序。

    这种模式可以扩展以允许根据需要发生更棘手的注册gubbins,因为模块本身现在负责自己的注册,而不是试图将所有特殊情况塞进一个注册函数中

    【讨论】:

    • 完美!我会试试的。如果每个模块都完全负责他们的路线,这是更好的解决方案。
    • 感谢您发布此信息。帮了我很多忙!
    【解决方案2】:

    编辑:

    要一次性创建一组mux.Route,您可以定义一个自定义类型(以下示例中的handler)并执行以下操作:

    package main
    
    import (
        "fmt"
        "github.com/gorilla/mux"
        "net/http"
    )
    
    type handler struct {
        path    string
        f       http.HandlerFunc
        methods []string
    }
    
    func makeHandlers(hs []handler, r *mux.Router) {
        for _, h := range hs {
            if len(h.methods) == 0 {
                r.HandleFunc(h.path, h.f)
            } else {
                r.HandleFunc(h.path, h.f).Methods(h.methods...)
            }
        }
    }
    
    // create some example handler functions
    
    func somePostHandler(w http.ResponseWriter, r *http.Request) {
        fmt.Fprint(w, "POST Handler")
    }
    
    func someHandler(w http.ResponseWriter, r *http.Request) {
        fmt.Fprint(w, "Normal Handler")
    }
    
    func main() {
        //define some handlers
        handlers := []handler{{path: "/", f: somePostHandler, methods: []string{"POST"}}, {path: "/", f: someHandler}}
        r := mux.NewRouter()
        http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./templates/static/"))))
        // Initialise the handlers
        makeHandlers(handlers, r)
        http.Handle("/", r)
        http.ListenAndServe(":8080", nil)
    }
    

    Playground

    原始答案:

    如果他们在same package 中,则不需要import

    您可以在urls.go 中定义URL 变量,然后在views.go(或package moduleX 中的另一个文件)中定义逻辑,只要它们具有相同的package 声明即可。

    例如:

    // moduleX/urls.go
    
    package moduleX
    
    var (
        urls = []string{"http://google.com/", "http://stackoverflow.com/"}
    )
    

    然后:

    // moduleX/views.go (or some other file in package moduleX)
    
    package moduleX
    
    func GetUrls() []string {
        return urls
    }
    

    然后:

    // start.go
    
    package main
    
    import (
        "fmt"
        "myapp/moduleX"
    )
    
    func main() {
        for _, url := range moduleX.GetUrls() {
            fmt.Println(url)
        }
    }
    

    或者,更简单的是,通过给它一个大写的名称,从 moduleX 包中导出变量。

    例如:

    // moduleX/urls.go
    
    package moduleX
    
    var URLs = []string{"http://google.com/", "http://stackoverflow.com/"}
    

    然后:

    // start.go
    
    package main    
    
    import (
        "fmt"
        "myapp/moduleX"
    )
    
    func main() {
        for _, url := range moduleX.URLs {
            fmt.Println(url)
        }
    }
    

    看看any of the Go source to see how they handle the same problem。一个很好的例子是the SHA512 source,其中冗长的变量存储在sha512block.go,逻辑在sha512.go

    【讨论】:

    • 可行,我知道这是可能的 - 但它不能直接解决我的问题。即使我将所有 URL 导出到 start.go,如何使用适当的处理程序为它们创建路由?我想在 moduleX/urls.go 中完成所有 HandleFunc()-stuff,然后在 start.go 中“使用”这些路由器(或 Routes 或 HandleFuncs?)。使用一个模块,我可以在 urls.go 中定义路由器并在 start.go 中使用它们,但是对于多个模块,我需要一种“附加”到路由器的方法。
    • 创建一个指向http.HandlerFuncs的url映射,然后创建一个函数将所有这些初始化为mux.Routes ?
    • 好的,现在我做了这样的事情:func GetRoutes() []core.Route { routes := []core.Route{ core.Route{URL: "/new/", Handler: NewObjHandler}, core.Route{URL: "/", Handler: login.LoginFirst(ListObjHandler)}, } return routes } 在我的 urls.go 和 obj_routes := obj.GetRoutes() s := r.PathPrefix("/obj/").Subrouter() for _, route := range obj_routes { s.HandleFunc(route.URL, route.Handler) } - 这有效,但看起来很难看。而且我现在不知道如何从 gorillas mux 应用.Methods("POST")
    • 太棒了,你的 makeHandlers 是 Methods() 工作所缺少的。对我有用。剩下的唯一问题是:我必须为每个模块编写module.GetRoutes()makeHandlers(moduleRoutes, subrouter)。估计没有别的办法了吧?
    • 抱歉,不确定您所说的“针对每个模块”是什么意思。如果您在包中使用上面的代码,您应该能够从moduleX(只需大写当前的handler 类型)和MakeHandlers() 函数(返回*mux.Router)导出通用Handler 类型.然后,任何导入包的代码都可以定义h := moduleX.Handler{path: "/", f: someHandler}等,然后调用r := moduleX.MakeHandlers。这应该将代码分开,只要您从 stringhttp.HandleFunc 和可变参数列表 ([]string) 中创建每个 moduleX.Handler
    猜你喜欢
    • 2018-07-14
    • 1970-01-01
    • 1970-01-01
    • 2015-06-09
    • 1970-01-01
    • 2020-10-03
    • 2018-11-12
    • 2019-05-04
    • 1970-01-01
    相关资源
    最近更新 更多