5

我的目录结构如下所示:

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了解所有文件中的所有 URL 。somemodule/urls.gomodule.GetURLs

4

2 回答 2

4

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

如果您在自己的 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,因为模块本身现在负责自己的注册,而不是试图将所有特殊情况塞进一个注册函数

于 2013-10-15T05:28:52.673 回答
3

编辑:

要一次性创建一组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)
}

操场

原始答案:

import如果它们在同一个包中,则不需要它们。

您可以在 中定义 URL 变量urls.go,然后在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)
    }
}

查看任何 Go 源代码,了解它们如何处理相同的问题。一个很好的例子是在SHA512代码中存储了冗长的变量sha512block.go并且逻辑在sha512.go.

于 2013-10-14T08:59:39.863 回答