# Setting a request header with or without Context in Golang

I have two ways (middleware) of setting a specific header (if not set) to request but want to know if one is better/beneficial than the other and the reasons why.

Note: At some point I will need to log X-Request-Id value in every single application log I have. If this plan affects your answer, I don't know. Just saying!

Context version

package middleware

import (
"context"
"net/http"
)

type CtxKey string
const CtxReqIdKey CtxKey = "X-Request-Id"

func RequestId(handler http.Handler) http.Handler {
return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if CtxKey == "" {
CtxKey = uuid.New().String()
}

ctx1 := context.WithValue(req.Context(), CtxReqIdKey, CtxKey)
ctx2 := req.WithContext(ctx1)

handler.ServeHTTP(res, ctx2)
})
}

# Elsewhere: request.Context().Value(middleware.CtxReqIdKey)


Without context version

package middleware

import (
"net/http"
)

func RequestId(handler http.Handler) http.Handler {
return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
}

handler.ServeHTTP(res, req)
})
}


Usage

err := http.ListenAndServe(":8080", middleware.RequestId(Router))

• passing the req-id to the context will let you track it within sub layer of your application like db requests by giving them the updated context. – mh-cbon Sep 15 at 10:27

Long form comment: Yes, the context version. I'd consider it a bad pattern to modify incoming data inline (because it's harder to track later what came in and what the application did with it). Especially in applications which do not only handle HTTP traffic, but also, say, gRPC calls, it's even more important that this data isn't stored for one type of handler only, but for all of them in a unified fashion. Plus, context is (for better and worse) a kitchen sink for all layers of the code, even in the deepest layers you'll still be able to get that ID for various purposes, maybe auditing, or so.