2013-10-14 50 views
5

我的目錄結構是這樣的:如何使用gorilla/mux分割多個文件中的URL?

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。

回答

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) 
} 

Playground

原來的答案:

,如果他們在你第不需要import他們e same package

可以在urls.go只要它們具有相同的package聲明定義URL變量,然後在views.go邏輯(或package moduleX另一個文件)。

例如:

// 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中。

+0

那工作,我知道這是可能的 - 但它不直接解決我的問題。即使我將所有URL導出到start.go,我如何使用適當的Handler爲它們創建一個Route?我想做所有HandleFunc() - moduleX/urls.go中的東西,然後在start.go中「使用」這些路由器(或Routes或HandleFuncs?)。有了一個模塊,我可以在urls.go中定義路由器並在start.go中使用它們,但是對於多個模塊,我需要一種「附加」到路由器的方法。 – Subito

+1

創建一個URL到'http.HandlerFunc's的映射,然後創建一個函數將所有這些初始化爲'mux.Route's? – Intermernet

+0

好了,現在我做了這樣的事:'FUNC GetRoutes()[] {core.Route \t路線:= [] {core.Route \t \t core.Route {URL: 「/新/」,處理程序:NewObjHandler }, \t \t core.Route {URL: 「/」,處理程序:login.LoginFirst(ListObjHandler)}, \t} \t返回路線 }'我urls.go和'obj_routes:= obj.GetRoutes() \t S:= r.PathPrefix( 「/ OBJ /」)Subrouter() \t爲_,路線:=範圍obj_routes { \t \t s.HandleFunc(route.URL,route.Handler) \t}' - 它工作,但看起來很醜。我不知道如何從大猩猩多路複用器上應用'.Methods(「POST」)'。 – Subito

4

爲什麼不讓處理程序將自己插入到路由表中?

如果要定義在它自己去文件中的每個處理,使用`的init()`FUNC每個文件的處理程序添加到全局路由表

因此,像:


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) 
} 

yourmodule.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 
} 

的init()被調用的包裝主要執行之前在包中的每個文件(),這樣你可以肯定的是,你踢的服務器關閉之前,所有的處理程序將被註冊。

這種模式可以擴展到允許更多調皮註冊格賓斯根據需要發生,因爲模塊本身現在對自己負責登記,而不是試圖將所有特殊情況下塞進一個註冊FUNC

+0

完美!我會嘗試。如果每個模塊完全掌管他們的路線,這是更好的解決方案。 – Subito

+0

感謝您發佈此信息。幫助我出去了很多! –

相關問題