0
votes

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?

2
Why would you need middleware without a handler? I think you are confusing the terms, and it sounds like you want this to be a handler itself instead of middleware.Gavin
That seems a good comment :-) If you set that as an answer I can accept it.Complexity
Can you describe what dynamicRouteMiddleware is meant to do [rather than the abstract example] - ? If you haven't added a route to your *mux.Router, nothing will match, and middleware isn't called without a match.elithrar

2 Answers

1
votes

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.

1
votes

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.