Complexity
Complexity

Reputation: 5820

Mux middleware without handler

I'm building an application using the Micro Service Architecture. On the gateway, I do want to route requests to the correct endpoints.

But, the endpoint are now known at runtime and needs to be configured in the DB.

Below if the code to get the router.

func getRouter() *mux.Router {
    r := mux.NewRouter()

    r.Use(dynamicRouteMiddleware)

    return r
}

The middleware itself is this:

func dynamicRouteMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Println("Error")
    })
}

However, the "Error" is never printed. It's only printed when I put a handler for '/'

How can I create middleware without handlers?

Upvotes: 0

Views: 646

Answers (2)

Seaskyways
Seaskyways

Reputation: 3795

It's called "middleware" because it's supposed to put your Handler in the "middle". It receives the input before your Handler, and receives the output of your Handler.

Inherently, to have your middleware work, you are required to have at least one Handler. Preferably you may just use this functionality that you need in the Handler rather than middleware.

Upvotes: 1

novalagung
novalagung

Reputation: 11502

On the middleware, you need call the next handler so all incoming requests will proceed to the destination route.

func dynamicRouteMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Println("Error")
        next.ServeHTTP(w, r) // <------- this one
    })
}

You can register any routes as you want, but in the very end make sure the r object used as handler of / route.

r.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("test"))
})

r.HandleFunc("/test/12", func(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("test 12"))
})

r.HandleFunc("/about-us", func(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("about us"))
})

http.Handle("/", r)
http.ListenAndServe(":8080", nil)

When you access /test, /test/12, or /about-us; the Error will still be printed.

Previously it's not printed because you don't proceed to the next handler. The code next.ServeHTTP(w, r) is mandatory in your case.

Upvotes: 1

Related Questions