From 2c424db6b126be15d75b5b36036a4201fb4fd9b0 Mon Sep 17 00:00:00 2001 From: Pascal Bleser Date: Fri, 11 Sep 2026 15:54:46 +0200 Subject: [PATCH] feat(graph): use chi HTTP response wrapper instead of a homegrown one * in the graph service's metrics, we use a homegrown response writer struct implementation to capture the status of the next handler's response: instead, use chi's implementation which is more sophisticated and battle tested --- services/graph/pkg/metrics/middleware.go | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/services/graph/pkg/metrics/middleware.go b/services/graph/pkg/metrics/middleware.go index 77624d6e7d..3a8ac996ba 100644 --- a/services/graph/pkg/metrics/middleware.go +++ b/services/graph/pkg/metrics/middleware.go @@ -6,18 +6,9 @@ import ( "time" "github.com/go-chi/chi/v5" + "github.com/go-chi/chi/v5/middleware" ) -type statusResponseWriter struct { - http.ResponseWriter - statusCode int -} - -func (rw *statusResponseWriter) WriteHeader(code int) { - rw.statusCode = code - rw.ResponseWriter.WriteHeader(code) -} - // A middleware that tracks the duration of every inbound Graph API HTTP call // and calls a function to delegate the storage of that duration into a // histogram metric, analyzing the incoming query and deconstructing it into @@ -34,11 +25,11 @@ func HTTPMetrics(inFlight *atomic.Int64, observe func(method, pattern string, st return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() - responseWrapper := &statusResponseWriter{ResponseWriter: w, statusCode: 200} // 200 OK is the default when it's not set inFlight.Add(1) defer inFlight.Add(-1) - next.ServeHTTP(responseWrapper, r) + wrapper := middleware.NewWrapResponseWriter(w, r.ProtoMajor) + next.ServeHTTP(wrapper, r) duration := time.Since(start) @@ -53,7 +44,7 @@ func HTTPMetrics(inFlight *atomic.Int64, observe func(method, pattern string, st } } - observe(r.Method, routePattern, responseWrapper.statusCode, duration) + observe(r.Method, routePattern, wrapper.Status(), duration) }) } }