web-dev-qa-db-fra.com

Intergiciel personnalisé Gorilla Mux

J'utilise gorilla mux pour gérer le routage. Ce qui me manque, c'est d'intégrer un middleware entre chaque requête.

Par exemple

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

Chaque demande entrante doit passer par le middleware. Comment puis-je intégrer ici un logiciel intermédiaire?

Mise à jour

Je vais l'utiliser en combinaison avec des gorilles/sessions, et ils disent:

Remarque importante: si vous n'utilisez pas gorilla/mux, vous devez envelopper vos gestionnaires avec context.ClearHandler car sinon vous perdrez de la mémoire! Un moyen simple de le faire consiste à envelopper le multiplexeur de niveau supérieur lors de l'appel à http.ListenAndServe:

Comment puis-je empêcher ce scénario?

27
zero_coding

Il suffit de créer un wrapper, c'est assez simple dans 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))
}
60
OneOfOne

Je ne sais pas pourquoi @OneOfOne a choisi de chaîner le routeur dans le middleware, je pense que c'est une meilleure approche:

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

Si vous souhaitez appliquer une chaîne middleware à toutes les routes d'un routeur ou d'un sous-routeur, vous pouvez utiliser un fork de Gorilla mux https://github.com/bezrukovspb/mux

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

Vous pourriez envisager un package de middleware tel que negroni .

1
kpublik
func Middleware(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // do stuff
        h.ServeHTTP(w, r)
    })
}

func main () {
    router := mux.NewRouter()
    router.Use(Middleware)
    // Add more middleware if you need
    // router.Use(Middleware2) 
    // router.Use(Middleware3)

    _ = http.ListenAndServe(":80", router)
}
0