2014-10-05 2 views
20

Ich benutze Gorilla Mux zum Verwalten von Routing. Was mir fehlt, ist eine Middleware zwischen jeder Anfrage zu integrieren.Gorilla mux benutzerdefinierte Middleware

Zum Beispiel

package main 

import (
    "fmt" 
    "github.com/gorilla/mux" 
    "log" 
    "net/http" 
    "strconv" 
) 

func HomeHandler(response http.ResponseWriter, request *http.Request) { 

    fmt.Fprintf(response, "Hello home") 
} 

func main() { 

    port := 3000 
    portstring := strconv.Itoa(port) 

    r := mux.NewRouter() 
    r.HandleFunc("/", HomeHandler) 
    http.Handle("/", r) 

    log.Print("Listening on port " + portstring + " ... ") 
    err := http.ListenAndServe(":"+portstring, nil) 
    if err != nil { 
     log.Fatal("ListenAndServe error: ", err) 
    } 
} 

Jede eingehende Anforderung sollte durch die Middleware übergeben. Wie kann ich hier eine Midleware integrieren?

aktualisieren

ich es in Kombination mit Gorilla/Sitzungen verwenden, und sie sagen:

Wichtiger Hinweis: Wenn Sie nicht Gorilla/Mux verwenden, müssen Sie Ihre wickeln Handler mit context.ClearHandler als oder sonst Sie Speicher verlieren! Eine einfache Möglichkeit, dies zu tun, ist den Top-Level-Mux zu wickeln, wenn http.ListenAndServe Aufruf:

Wie kann ich dieses Szenario verhindern?

+0

Für diejenigen, die hier gelandet: "Gorilla/Mux" hat jetzt integrierte Middleware-Behandlung: https://github.com/gorilla/mux#middleware – kaustavdm

Antwort

47

Erstellen Sie einfach einen Wrapper, es ist ziemlich einfach, in Go:

func HomeHandler(response http.ResponseWriter, request *http.Request) { 

    fmt.Fprintf(response, "Hello home") 
} 

func Middleware(h http.Handler) http.Handler { 
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 
     log.Println("middleware", r.URL) 
     h.ServeHTTP(w, r) 
    }) 
} 
func main() { 
    r := mux.NewRouter() 
    r.HandleFunc("/", HomeHandler) 
    http.Handle("/", Middleware(r)) 
} 
+2

Danke dafür, 'h.ServeHTTP (w, r)' dieser Teil ist was ich vermisste. Sie machen es nicht sehr klar, wie man einen Handler direkt anruft. – tkiethanom

1

Sie könnten ein Middleware-Paket wie negroni in Betracht ziehen.

+0

Wenn ich es Gorilla/Sitzungen verwenden würde, würde es Speicherleck nicht passieren? –

3

Ich bin nicht sicher, warum @OneOfOne Ketten Router in die Middleware gewählt haben, ich denke, das ist besser Ansatz gering ist:

func main() { 
    r.Handle("/",Middleware(http.HandlerFunc(homeHandler))) 
    http.Handle("/", r) 
} 

func Middleware(h http.Handler) http.Handler { 
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 
    h.ServeHTTP(w, r) 
})} 
+0

Dieser Ansatz war genau das, wonach ich suchte - ein verschachteltes 'Handle' mit Middleware. Vielen Dank! –

1

Wenn Sie möchten, eine Middleware-Kette zu allen Routen eines Routers bewerben oder-Sub Sie eine Gabel von Gorilla-Mux können https://github.com/bezrukovspb/mux

subRouter := router.PathPrefix("/use-a-b").Subrouter().Use(middlewareA, middlewareB) 
subRouter.Path("/hello").HandlerFunc(requestHandlerFunc) 
+0

Danke, Alter! Diese express.js Middleware-Stil war genau das, was ich suchte – nxrd

+0

Middleware Verwendung ist jetzt in Gorilla Mux eingebaut – ozy