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)
})
}
}