gorilla / mux

Package gorilla/mux is a powerful HTTP router and URL matcher for building Go web servers with 🦍
https://gorilla.github.io
BSD 3-Clause "New" or "Revised" License
20.93k stars 1.85k forks source link

[question] question about Router.Match #683

Open dongzeXD opened 2 years ago

dongzeXD commented 2 years ago

location package mux. mux.go Does this mean that each Match has to construct a invoke chain?

image
amustaque97 commented 2 years ago

I couldn't get your question correctly! Could you explain it with an example or some minimal code?

If you're asking that for each route, the Match method will construct middleware even though it is not defined for routes like: second-route and third-route? Then yes, r.middleware is defined as a global so whenever there is any new middleware then it will update the middleware slice here and will be applied to all the routes.

package main

import (
    "fmt"
    "net/http"

    "github.com/gorilla/mux"
)

func loggingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Do stuff here
        fmt.Println(r.RequestURI + " logging middleware")
        // Call the next handler, which can be another middleware in the chain, or the final handler.
        next.ServeHTTP(w, r)
    })
}

func AuthenticationMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Do stuff here
        fmt.Println(r.RequestURI + " authentication middleware")
        // Call the next handler, which can be another middleware in the chain, or the final handler.
        next.ServeHTTP(w, r)
    })
}
func AuthorizationMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Do stuff here
        fmt.Println(r.RequestURI + " authorization middleware")
        // Call the next handler, which can be another middleware in the chain, or the final handler.
        next.ServeHTTP(w, r)
    })
}

func handler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello, world"))
}

func secondHandler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello, world"))
}

func thirdHandler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello, world"))
}
func main() {
    r := mux.NewRouter()
    r.HandleFunc("/", handler)
    r.Use(loggingMiddleware)
    r.Use(AuthenticationMiddleware)
    r.Use(AuthorizationMiddleware)

    r.HandleFunc("/second-route", secondHandler)

    r.HandleFunc("/third-route", thirdHandler)
    http.ListenAndServe(":8000", r)
}

Call the API:

curl localhost:8000/second-route

Log output:

/second-routelogging middleware
/second-routeauthentication middleware
/second-routeauthorization middleware

In simple terms. Middlewares are applicable to all the routes unless any middleware doesn't call next.ServeHTTP()

I would recommend you to go through the comment https://github.com/gorilla/mux/issues/445#issuecomment-463220765

ianling commented 2 years ago

@dongzeXD can this be closed, or is there any additional info you need?