2014-10-06 2 views
12

Ich versuche, mein Datenbankobjekt an meine Handler zu übergeben, anstatt ein globales Objekt zu haben. Aber ich weiß nicht, ob das möglich ist, ich benutze Gorilla Mux Paket, und ich kann sehen, dass es eine Schließung als zweiten Parameter braucht.Wie übergebe ich Argumente an meinen Handler

Was definiert dann die Parameter, die ich verwenden kann, idealerweise möchte ich einen dritten Parameter wie diesen haben.

// In my main 
router.HandleFunc("https://stackoverflow.com/users/{id}", showUserHandler).Methods("GET") 

func showUserHandler(w http.ResponseWriter, r *http.Request, db *gorm.DB) { 
    fmt.Fprintf(w, "We should fetch the user with id %s", vars["id"]) 
} 

Gibt es einen Workaround? Oder brauche ich ein globales DB-Objekt? Ich bin neu in Go, also erkläre bitte eine mögliche Antwort im Detail.

+2

http://stackoverflow.com/a/26106655/6309 können Sie auch ein paar Ideen. – VonC

+0

@VonC Ich habe tatsächlich versucht http://simonsdotnet.wordpress.com/2014/09/06/extiging-gos-http-handlers/ aber festgestellt, dass es nicht mit Gorilla funktioniert, da das http-Paket nur die ServeHTTP will, aber der Gorilla will eine Funktion mit bestimmten Parametern. Ich könnte falsch liegen. – MartinElvar

Antwort

22

Willkommen bei Go.

Es ist akzeptabel, globale Variablen und speziell Datenbankobjekte zu haben.

Es gibt jedoch einige Möglichkeiten zur Problemumgehung, wenn Sie nicht möchten, zum Beispiel können Sie eine Struktur erstellen und definieren Sie Ihre showHandler darauf.

type Users struct { 
    db *gorm.DB 
} 

func (users *Users) showHandler(w http.ResponseWriter, r *http.Request) { 
    //now you can use users.db 
} 
func (users *Users) addHandler(w http.ResponseWriter, r *http.Request) { 
    //now you can use users.db 
} 

// setup 
users := &Users{db: createDB()} 
router.HandleFunc("https://stackoverflow.com/users/{id}", users.showHandler).Methods("GET") 
router.HandleFunc("https://stackoverflow.com/users/new", users.addHandler) 
//etc 

Ein weiterer Ansatz ist die Schaffung einer Wrapper-Funktion:

db := createDB() 
router.HandleFunc("https://stackoverflow.com/users/{id}", func(w http.ResponseWriter, r *http.Request) { 
    showUserHandler(w, r, db) 
}).Method("GET") 
+0

Danke OneOfOne. Die Idee war, dass ich eine mehr DI-Art davon machen wollte, vielleicht überschätze ich es. Welche Lösung wäre die sauberste? – MartinElvar

+0

@MartinElvar für eine Datenbankverbindung würde ich sagen, eine globale Variable ist in Ordnung. Wenn Sie bestimmte Variablen möchten, die nur von einer bestimmten Gruppe von Funktionen verwendet werden können, dann die Strukturlösung. – OneOfOne

+0

@MartinElvar auch daran erinnern, dass während die meisten Datenbank-Handler für Nebenläufigkeit sicher sind, alles andere nicht, wenn Sie also eine Variable in einem Handler setzen und es in einem anderen holen, müssen Sie eine Art von Sperren verwenden. – OneOfOne