2013-10-14 20 views
5

mia struttura di directory simile a questo:Come divido gli URL in più file usando gorilla/mux?

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

L'applicazione viene avviato con start.go e da lì a configurare tutti i percorsi e importare i gestori da moduleX/views.go come questo:

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

Ora voglio aggiungi altri moduli e chiediti se (e come) è possibile definire gli URL nel modulo in un file urls.go e in qualche modo "importarli" in start.go. Nello specifico voglio che lo start.go conosca tutti gli URL di tutti i file somemodule/urls.go con una sola importazione o qualche tipo di una funzione module.GetURLs.

risposta

3

EDIT:

Per creare un gruppo di mux.Route 's in una sola volta, è possibile definire un tipo personalizzato (handler nell'esempio sotto) e non fare qualcosa di simile:

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

RISPOSTA ORIGINALE:

non è necessario a import loro se sono in th e same package.

È possibile definire le variabili URL in urls.go, e quindi la logica in views.go (o un altro file in package moduleX), purché abbiano la stessa package dichiarazione.

Per esempio:

// moduleX/urls.go 

package moduleX 

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

Poi:

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

package moduleX 

func GetUrls() []string { 
    return urls 
} 

Poi:

// start.go 

package main 

import (
    "fmt" 
    "myapp/moduleX" 
) 

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

Oppure, ancora più semplice, basta esportare la variabile dal pacchetto moduleX dandogli un capitalizzata nome.

Per esempio:

// moduleX/urls.go 

package moduleX 

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

e poi:

// start.go 

package main  

import (
    "fmt" 
    "myapp/moduleX" 
) 

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

Dai un'occhiata alla any of the Go source to see how they handle the same problem. Un buon esempio è in the SHA512 source dove la variabile lunga è memorizzata in sha512block.go e la logica è in sha512.go.

+0

che funziona e sono consapevole che ciò è possibile, ma non risolve il mio problema direttamente. Anche se ottengo tutti gli URL esportati su start.go, come posso creare un percorso per loro con l'Handler appropriato? Voglio fare tutto il HandleFunc() - roba in moduleX/urls.go e poi "usare" questi Router (o Routes o HandleFuncs?) In start.go. Con un modulo potrei semplicemente definire il router in urls.go e usarli in start.go, ma con più moduli ho bisogno di un modo per "accodare" al router. – Subito

+1

Crea una mappa di urls a 'httpHandlerFunc's, quindi crea una funzione per inizializzare tutte quelle come' mux.Route's? – Intermernet

+0

OK, ora ho fatto qualcosa di simile: 'GetRoutes func() [] {core.Route \t itinerari: = [] core.Route { \t \t core.Route {URL: "/ new /", Handler: NewObjHandler }, \t \t core.Route {URL: "/", Handler: login.LoginFirst (ListObjHandler)}, \t} \t percorsi di ritorno } 'nel mio urls.go e' obj_routes: = obj.GetRoutes() \t s:. = r.PathPrefix ("/ obj /") Subrouter() \t per _, percorso: = variano obj_routes { \t \t s.HandleFunc (route.URL, route.Handler) \t} '- che funziona, ma sembra brutto. E non so come posso applicare il '.Methods (" POST ")' di gorillas mux ora. – Subito

4

Perché non chiedere ai gestori di inserirsi nella tabella dei percorsi?

Se si sta definendo ogni gestore nel proprio file Vai, utilizzare il init func() `per ogni file per aggiungere il gestore a una tabella di routing globale

Quindi qualcosa di simile:


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() viene chiamato per ogni file in un pacchetto prima esecuzione del pacchetto main() in modo da poter essere sicuri che tutti i gestori saranno registrate prima di calciare il server off.

Questo modello può essere esteso per consentire Gubbins di registrazione più furbata per accadere, se necessario, dal momento che i moduli stessi sono ora responsabile della propria registrazione, invece di cercare di stipare tutti i casi particolari in un unico func registrazione

+0

perfetto! Ci proverò. Se ogni modulo è completamente responsabile dei loro percorsi, questa è la soluzione migliore. – Subito

+0

Grazie per aver postato questo. Mi ha aiutato molto! –