core/crm-core/internal/api/http/middleware.go
2025-12-27 14:32:00 -03:00

62 lines
1.4 KiB
Go

package httpapi
import (
"context"
"log/slog"
"net/http"
"time"
"github.com/google/uuid"
)
type ctxKey string
const requestIDKey ctxKey = "request_id"
func RequestID(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
requestID := r.Header.Get("X-Request-Id")
if requestID == "" {
requestID = uuid.NewString()
}
w.Header().Set("X-Request-Id", requestID)
ctx := context.WithValue(r.Context(), requestIDKey, requestID)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
func RequestIDFromContext(ctx context.Context) string {
val := ctx.Value(requestIDKey)
if val == nil {
return ""
}
id, _ := val.(string)
return id
}
func Logging(logger *slog.Logger) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
ww := &responseWriter{ResponseWriter: w, status: http.StatusOK}
next.ServeHTTP(ww, r)
logger.Info("request",
"method", r.Method,
"path", r.URL.Path,
"status", ww.status,
"duration_ms", time.Since(start).Milliseconds(),
"request_id", RequestIDFromContext(r.Context()),
)
})
}
}
type responseWriter struct {
http.ResponseWriter
status int
}
func (w *responseWriter) WriteHeader(status int) {
w.status = status
w.ResponseWriter.WriteHeader(status)
}