在golang中,条件链接HTTP处理程序

huangapple go评论76阅读模式
英文:

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).ServeHTTP(w, r)
            } 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没有被调用。如何根据条件进行链式调用?

英文:

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?

答案1

得分: 3

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

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)
			}
		})
	}
}
英文:

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

答案2

得分: 1

你的函数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)
    }
}
英文:

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

<pre>

package main

import &quot;fmt&quot;

func main() {
	test(&quot;Eugene&quot;)
}

func test(name string) func() {
	return func() {
		fmt.Println(&quot;Hello! &quot; + name)
	}
}

</pre>

As you can see, output empty

But this code will work right

<pre>
package main

import &quot;fmt&quot;

func main() {
	test(&quot;Eugene&quot;)()
}

func test(name string) func() {
    return func() {
        fmt.Println(&quot;Hello! &quot; + name)
    }
}

</pre>

huangapple
  • 本文由 发表于 2021年11月23日 15:41:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/70077038.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定