2013-10-14 4 views
5

Meine Verzeichnisstruktur sieht wie folgt aus:Wie teile ich URLs in mehrere Dateien mit Gorilla/Mux?

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

Die App mit start.go und es losgeht aus ich alle Routen konfigurieren und die Handler von moduleX/views.go wie folgt importieren:

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

Jetzt möchte ich fügen Sie weitere Module hinzu und fragen Sie mich, ob (und wie) es möglich ist, die URLs in dem Modul in einer urls.go Datei zu definieren und sie irgendwie in start.go zu "importieren". Spezifisch möchte ich start.go, um alle URLs in allen somemodule/urls.go Dateien mit nur einem Import oder irgendeiner Art einer module.GetURLs Funktion zu wissen.

Antwort

3

EDIT:

Um eine Gruppe von mux.Route ‚s in einem Rutsch zu erstellen, können Sie einen benutzerdefinierten Typen (handler im Beispiel unten) definieren und tun so etwas wie:

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

ORIGINAL ANTWORT:

Sie brauchen nicht zu import sie, wenn sie in th sind e same package.

Sie können die URL-Variablen in urls.go definieren und dann die Logik in views.go (oder eine andere Datei in package moduleX), solange sie die gleiche package Erklärung haben.

Zum Beispiel:

// moduleX/urls.go 

package moduleX 

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

Dann:

// moduleX/views.go (or some other file in package moduleX) 

package moduleX 

func GetUrls() []string { 
    return urls 
} 

Dann:

// start.go 

package main 

import (
    "fmt" 
    "myapp/moduleX" 
) 

func main() { 
    for _, url := range moduleX.GetUrls() { 
     fmt.Println(url) 
    } 
} 

Oder, noch einfacher, exportiert nur die Variable aus dem moduleX Paket durch eine aktivierte geben Name.

Zum Beispiel:

// moduleX/urls.go 

package moduleX 

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

und dann:

// start.go 

package main  

import (
    "fmt" 
    "myapp/moduleX" 
) 

func main() { 
    for _, url := range moduleX.URLs { 
     fmt.Println(url) 
    } 
} 

Werfen Sie einen Blick auf any of the Go source to see how they handle the same problem. Ein gutes Beispiel ist the SHA512 source, wo die lange Variable in sha512block.go gespeichert ist und die Logik in sha512.go ist.

+0

dass zu stopfen funktioniert und mir ist bewusst, dass dies möglich ist - aber es löst mein Problem nicht direkt. Auch wenn ich alle URLs nach start.go exportieren lasse, wie kann ich mit dem entsprechenden Handler eine Route für sie erstellen? Ich möchte alle HandleFunc() - Sachen in moduleX/urls.go machen und dann diese Router (oder Routes oder HandleFuncs?) In start.go benutzen. Mit einem Modul könnte ich den Router einfach in urls.go definieren und in start.go verwenden, aber mit mehreren Modulen brauche ich eine Möglichkeit, den Router anzuhängen. – Subito

+1

Erstellen Sie eine Karte von URLs zu 'http.HandlerFunc's, dann erstellen Sie eine Funktion, um all diese als 'mux.Route's zu initialisieren? – Intermernet

+0

OK, jetzt habe ich etwas wie folgt aus: 'func GetRoutes() [] {core.Route \t Routen: = [] core.Route { \t \t core.Route {URL: "/ neu /" Handler: NewObjHandler }, \t \t core.Route {URL: "/", Handler: login.LoginFirst (ListObjHandler)}, \t} \t Rückkehr Routen } 'in meinem urls.go und' obj_routes: = obj.GetRoutes() \t s:. = r.PathPrefix ("/ obj /")-Sub() \t für _, route: = range obj_routes { \t \t s.HandleFunc (route.URL, route.Handler) \t} '- was funktioniert, sieht aber hässlich aus. Und ich weiß nicht, wie ich jetzt die .Methods ("POST") von Gorillas mux anwenden kann. – Subito

4

Warum nicht die Handler dazu bringen, sich in die routes-Tabelle einzufügen?

Wenn Sie jeden Handler in seinem eigenen Go-Datei sind zu definieren, verwenden Sie die `init()` func für jede Datei die Prozedur zu einem globalen Routing-Tabelle

So etwas wie hinzufügen:


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() für jede Datei in einem Paket vor der Ausführung des Pakets main() aufgerufen wird, so können Sie sicher sein, dass alle Handler registriert werden, bevor Sie den Server aus zu treten.

Dieses Muster für mehr tricksy Registrierung gubbins verlängert werden, damit je nach Bedarf geschehen, da die Module selbst jetzt verantwortlich für ihre eigene Registrierung ist, anstatt alle Sonderfälle in eine Registrierung func versuchen

+0

perfekt! Ich werde das versuchen. Wenn jedes Modul vollständig für seine Routen verantwortlich ist, ist dies die bessere Lösung. – Subito

+0

Danke für das Posten. Hat mir sehr geholfen! –