【问题标题】:Passing Data from Handler to Middleware After Serving Request in Golang在 Golang 中处理请求后将数据从处理程序传递到中间件
【发布时间】:2023-02-17 00:12:50
【问题描述】:

我在 Golang 中有以下简单的 API:

package main

import (
    "context"
    "fmt"
    "net/http"

    "github.com/gorilla/mux"
)

func middleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Call the handler
        next.ServeHTTP(w, r)

        // Retrieve custom data from the request object after the request is served
        customData := r.Context().Value("custom_data")
        fmt.Println("Custom data:", customData)
    })
}

func handler(w http.ResponseWriter, reqIn *http.Request) {
    reqIn = reqIn.WithContext(context.WithValue(reqIn.Context(), "custom_data", true))
}

func main() {
    r := mux.NewRouter()
    // Attach the middleware to the router
    r.Use(middleware)
    // Attach the handler to the router
    r.HandleFunc("/", handler).Methods("GET")
    http.ListenAndServe(":8080", r)
}

我希望中间件中的上下文能够访问“custom_data”的值,但它不能访问该上下文值。 即使我使用 Clone 而不是 WithContext 在请求的上下文中添加值,也会发生这种情况。

环顾四周,特别是这个post,如果我改为使用它作为处理程序:

func handler(w http.ResponseWriter, reqIn *http.Request) {
    req := reqIn.WithContext(context.WithValue(reqIn.Context(), "custom_data", true))
    *reqIn = *req
}

它按预期工作。 但是修改 *http.Request 是不规范的。

我要解决的真正问题是;如何将信息从处理程序传递到中间件?

  • 将值添加到 *http.Request 的上下文将能够在中间件中访问。

【问题讨论】:

  • 但是中间件是在处理程序之前处理的。

标签: api go pointers go-context


【解决方案1】:

您可以执行以下操作:

func middleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        custom_data := make(map[string]any)
        r = r.WithContext(context.WithValue(r.Context(), "custom_data", custom_data))

        // Call the handler
        next.ServeHTTP(w, r)

        // Retrieve custom data from the request object after the request is served
        v := r.Context().Value("custom_data")
        fmt.Printf("Custom data(%T): %v
", v, v)

        // or use the above defined map directly
        fmt.Printf("Custom data(%T): %v
", custom_data, custom_data)
    })
}

func handler(w http.ResponseWriter, r *http.Request) {
    m, ok := r.Context().Value("custom_data").(map[string]any)
    if ok && m != nil {
        m["value"] = true
    }
}

【讨论】:

    猜你喜欢
    • 2015-10-08
    • 1970-01-01
    • 2018-02-21
    • 2019-09-18
    • 1970-01-01
    • 2020-01-06
    • 1970-01-01
    • 2012-01-08
    相关资源
    最近更新 更多