Little Code
Little Code

Reputation: 1545

Go chi middleware to add item to response header

My concept is simple, I would like to add the request ID (generated by chi middleware.RequestID to the response header).

My code below adds X-Request-Id but does not add the ID itself. I am not sure why, since surely it is available in the context because middleware.RequestID is higher up in the middleware chain ?

My router creation:

package rest

import (
    "time"

    "github.com/go-chi/chi/v5"
    "github.com/go-chi/chi/v5/middleware"
    "goWebAPI/pkg/database"
    "goWebAPI/pkg/rest/mw"
    "goWebAPI/pkg/rest/routes"
)

func GetRouter(db *database.Database) *chi.Mux {
    r := chi.NewRouter()
    r.Use(middleware.RequestID)
    r.Use(mw.SendRequestID)
    r.Use(middleware.RealIP)
    r.Use(middleware.Logger)
    r.Use(middleware.Recoverer)
    r.Use(middleware.Timeout(60 * time.Second))
    r.Get("/", routes.IndexRoute())
    return r
}

My custom middleware:

package mw

import (
    "context"
    "net/http"

    "github.com/go-chi/chi/v5/middleware"
)

const requestIDHeader = "X-Request-Id"

func SendRequestID(next http.Handler) http.Handler {
    fn := func(w http.ResponseWriter, r *http.Request) {
        ctx := r.Context()
        if w.Header().Get(requestIDHeader) == "" {
            w.Header().Add(
                requestIDHeader,
                middleware.GetReqID(context.Background()),
            )
        }
        next.ServeHTTP(w, r.WithContext(ctx))
    }
    return http.HandlerFunc(fn)
}

My Index Route:

package routes

import "net/http"

func IndexRoute() http.HandlerFunc {
    fn:= func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("welcome"))
    }
    return fn
}

Upvotes: 0

Views: 5841

Answers (1)

Adrian
Adrian

Reputation: 46452

I believe your issue is here:

middleware.GetReqID(context.Background())

This tries to get the request ID of a new, empty context, but you need the request ID for the current request, meaning it should be:

middleware.GetReqID(r.Context())

(Or, since you're already grabbing the request context in local ctx, you could also use that.)

This is documented in GetReqId (emphasis mine):

GetReqID returns a request ID from the given context if one is present. Returns the empty string if a request ID cannot be found.

Upvotes: 5

Related Questions