golang 中 http 处理程序的条件链接

Conditional Chaining of http handlers in golang

我想根据特定条件有条件地添加 http 处理程序

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, .........)

当我测试时,没有调用 SpecificCheck HandlerFunc。 我如何根据条件链接它?

您的函数 SpecificCheck 仅返回匿名函数,但未调用它。您必须添加返回函数的调用,例如 SpecificCheck(arg)()

例如


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

如你所见,输出为空

但是这段代码可以正常工作

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

SepecificCheck 只是 returns 一个接受一个处理程序和 returns 另一个处理程序的函数,它不执行任何返回的对象。如果你想执行这些对象,你必须明确地执行,例如

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

上面的代码立即调用 SepecificCheck 返回的中间件函数,然后在该中间件函数返回的处理程序上调用 ServeHTTP 方法。

然后更新后的 ConditionalCheck 需要以下内容:

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