I am using context to attach user payload(userId specifically) in a middleware for my go rest application
// middleware
// attaching payload to the request context
claimsWithPayload, _ := token.Claims.(*handlers.Claims)
ctx := context.WithValue(r.Context(), "userid", claimsWithPayload.Id)
req := r.WithContext(ctx)
h := http.HandlerFunc(handler)
h.ServeHTTP(w, req)
And later in a http handler, I need to extract that userid as string/integer
but context().Value() returns an interface{}
// handler
a := r.Context().Value("userid") // THIS returns an interface{}
response := []byte("Your user ID is" + a) // 👈 how do I use it as a string/integer??
w.Write(response)
>Solution :
You can use a type assertion to get the context value as its underlying type:
a := r.Context().Value("userid").(string)
This will panic if the value stored by the middleware is not a string, or if something else sets the context key to something which is not a string. To guard against this you should never use builtin types as context keys, instead define your own type and use that:
type contextKey string
const userIDKey contextKey = "userid"
...
ctx := context.WithValue(r.Context(), userIDKey, claimsWithPayload.Id)
...
a := r.Context().Value(userIDKey).(string)
Because contextKey and userIDKey are unexported, only your package can read or write this value from or to the context.