Home > Mobile >  Conditional Chaining of http handlers in golang
Conditional Chaining of http handlers in golang

Time:11-23

I want to conditionally add http handler based on certain condition

func ConditionalCheck(arg string) func(http.Handler) http.Handler {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            ctx := r.Context()
            check, ok := ctx.Value("specific").(bool);
            if check {
                SpecificCheck(arg)
            } else {
                next.ServeHTTP(w, r)
            }
        })
    }
}

func SpecificCheck(arg string) func(http.Handler) http.Handler {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            // something
            next.ServeHTTP(w, r)
        })
    }
}

chain := alice.New(ConditionalCheck, .........)

When I test, the SpecificCheck HandlerFunc is not getting invoked. How do I chain this based on condition?

CodePudding user response:

Your function SpecificCheck is returning anonymus function only, but not calling it. You have to add call of returned function, like this SpecificCheck(arg)()

For example

    package main
    
    import "fmt"
    
    func main() {
        test("Eugene")
    }
    
    func test(name string) func() {
        return func() {
            fmt.Println("Hello! "   name)
        }
    }

As you can see, output empty

But this code will work right

    package main
    
    import "fmt"
    
    func main() {
        test("Eugene")()
    }
    
    func test(name string) func() {
        return func() {
            fmt.Println("Hello! "   name)
        }
    }

CodePudding user response:

SepecificCheck just returns a function that takes one handler and returns another, it does not execute any of those returned objects. If you want to execute those objects you must do so explicitly, e.g.

SepecificCheck(arg)(next).ServeHTTP(w, r)

The above immediately calls the middleware function returned by SepecificCheck and then invokes the ServeHTTP method on the handler returned by that middleware function.

Then the updated ConditionalCheck would like the following:

func ConditionalCheck(arg string) func(http.Handler) http.Handler {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            ctx := r.Context()
            check, ok := ctx.Value("specific").(bool)
            if check {
                SpecificCheck(arg)(next).ServeHTTP(w, r)
            } else {
                next.ServeHTTP(w, r)
            }
        })
    }
}
  • Related