如何将值从子中间件传播到父中间件?

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)