如何将值从子中间件传播到父中间件?
How to propagate value from child middleware to parent?
我正在尝试通过中间件模式自定义请求管道,代码如下:
func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Println("Hello, middleware!")
}
func middleware1(next http.HandlerFunc) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
fmt.Println("[START] middleware1")
ctx := r.Context()
ctx = context.WithValue(ctx, middleware1Key, middleware1Value)
r = r.WithContext(ctx)
next(w, r)
fmt.Println("[END] middleware1")
ctx = r.Context()
if val, ok := ctx.Value(middleware2Key).(string); ok {
fmt.Printf("Value from middleware2 %s \n", val)
}
}
}
func middleware2(next http.HandlerFunc) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
fmt.Println("[START] middleware2")
ctx := r.Context()
if val, ok := ctx.Value(middleware1Key).(string); ok {
fmt.Printf("Value from middleware1 %s \n", val)
}
ctx = context.WithValue(ctx, middleware2Key, middleware2Value)
r = r.WithContext(ctx)
next(w, r)
fmt.Println("[END] middleware2")
}
}
func main() {
mux := http.NewServeMux()
middlewares := newMws(middleware1, middleware2)
mux.HandleFunc("/hello", middlewares.then(helloHandler))
if err := http.ListenAndServe(":8080", mux); err != nil {
panic(err)
}
}
输出为:
[START] middleware1
[START] middleware2
Value from middleware1 middleware1Value
Hello, middleware!
[END] middleware2
[END] middleware1
根据输出,该值可以从父级传递给子级,而如果子级向上下文添加某些内容,父级将看不到它
如何将值从子中间件传播到父中间件?
您正在做的是通过 WithContext
方法创建一个指向修改后的 http.Request 的新指针。因此,如果您将它传递给链中的下一个中间件,一切都会按预期工作,因为您将这个新指针作为参数传递。
如果要修改请求并使其对持有指向它的指针的人可见,则需要取消引用指针并设置修改后的值。
所以在你的 'child' 中间件中而不是:
r = r.WithContext(ctx)
只需执行以下操作:
*r = *r.WithContext(ctx)
我正在尝试通过中间件模式自定义请求管道,代码如下:
func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Println("Hello, middleware!")
}
func middleware1(next http.HandlerFunc) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
fmt.Println("[START] middleware1")
ctx := r.Context()
ctx = context.WithValue(ctx, middleware1Key, middleware1Value)
r = r.WithContext(ctx)
next(w, r)
fmt.Println("[END] middleware1")
ctx = r.Context()
if val, ok := ctx.Value(middleware2Key).(string); ok {
fmt.Printf("Value from middleware2 %s \n", val)
}
}
}
func middleware2(next http.HandlerFunc) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
fmt.Println("[START] middleware2")
ctx := r.Context()
if val, ok := ctx.Value(middleware1Key).(string); ok {
fmt.Printf("Value from middleware1 %s \n", val)
}
ctx = context.WithValue(ctx, middleware2Key, middleware2Value)
r = r.WithContext(ctx)
next(w, r)
fmt.Println("[END] middleware2")
}
}
func main() {
mux := http.NewServeMux()
middlewares := newMws(middleware1, middleware2)
mux.HandleFunc("/hello", middlewares.then(helloHandler))
if err := http.ListenAndServe(":8080", mux); err != nil {
panic(err)
}
}
输出为:
[START] middleware1
[START] middleware2
Value from middleware1 middleware1Value
Hello, middleware!
[END] middleware2
[END] middleware1
根据输出,该值可以从父级传递给子级,而如果子级向上下文添加某些内容,父级将看不到它
如何将值从子中间件传播到父中间件?
您正在做的是通过 WithContext
方法创建一个指向修改后的 http.Request 的新指针。因此,如果您将它传递给链中的下一个中间件,一切都会按预期工作,因为您将这个新指针作为参数传递。
如果要修改请求并使其对持有指向它的指针的人可见,则需要取消引用指针并设置修改后的值。
所以在你的 'child' 中间件中而不是:
r = r.WithContext(ctx)
只需执行以下操作:
*r = *r.WithContext(ctx)