Skip to content

Commit 5a135af

Browse files
Refactor authz server: extract router setup and JSON response helper
Complexity reduction: - Extract 30+ line router setup logic into setupRouter() method - Significantly reduce New() function complexity (was 163+ lines) - Create writeJSONResponse() helper to eliminate code duplication - Replace repeated json.NewEncoder().Encode() patterns with helper Function improvements: - setupRouter(): Centralizes middleware and route configuration - writeJSONResponse(): Handles JSON responses with proper headers consistently - Reduces cyclomatic complexity in main constructor - Eliminates 4 instances of duplicate JSON encoding logic This makes the code more maintainable, testable, and reduces the complexity of the main server initialization function. Co-authored-by: Amp <amp@ampcode.com> Amp-Thread-ID: https://ampcode.com/threads/T-5be4213f-26eb-400c-bb7b-d4c79b7ee6fe
1 parent b22f78e commit 5a135af

File tree

1 file changed

+49
-39
lines changed

1 file changed

+49
-39
lines changed

services/authz/server/server.go

Lines changed: 49 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -155,38 +155,7 @@ func New(cfg Config) (*Server, error) {
155155
retryCfg: retryCfg,
156156
}
157157

158-
// Create chi router with middleware
159-
r := chi.NewRouter()
160-
telemetry.InstrumentRouter(r, "authz")
161-
162-
// Add middleware
163-
r.Use(middleware.RequestID)
164-
r.Use(s.loggingMiddleware)
165-
r.Use(s.metricsMiddleware)
166-
r.Use(middleware.Recoverer)
167-
r.Use(middleware.Timeout(defaultReadTimeout))
168-
169-
// Health and metrics endpoints
170-
r.Get("/health", s.healthHandler)
171-
r.Get("/metrics", promhttp.Handler().ServeHTTP)
172-
173-
// API routes
174-
r.Route("/v1", func(r chi.Router) {
175-
r.Route("/auth", func(r chi.Router) {
176-
r.Post("/verify", s.verifyHandler)
177-
r.Post("/check", s.envoyAuthHandler)
178-
r.Post("/mfa/verify-envoy", s.mfaVerifyHandler)
179-
})
180-
181-
r.Route("/certs", func(r chi.Router) {
182-
r.Post("/device", s.deviceCertHandler)
183-
r.Get("/ca", s.caHandler)
184-
})
185-
186-
r.Route("/tailscale", func(r chi.Router) {
187-
r.Get("/status", s.tailscaleStatusHandler)
188-
})
189-
})
158+
r := s.setupRouter()
190159

191160
useTLS := cfg.TLSCertPath != emptyString && cfg.TLSKeyPath != emptyString
192161
if useTLS {
@@ -314,9 +283,8 @@ func (s *Server) healthHandler(w http.ResponseWriter, _ *http.Request) {
314283
"tailscale": s.getTailscaleInfo(),
315284
}
316285

317-
w.Header().Set(contentTypeHeader, applicationJSON)
318286
w.WriteHeader(http.StatusOK)
319-
if err := json.NewEncoder(w).Encode(health); err != nil {
287+
if err := writeJSONResponse(w, health); err != nil {
320288
log.Printf("failed to encode health response: %v", err)
321289
}
322290
}
@@ -355,7 +323,7 @@ func (s *Server) verifyHandler(w http.ResponseWriter, r *http.Request) {
355323
return
356324
}
357325

358-
if err := json.NewEncoder(w).Encode(verifyResponse{Decision: decision}); err != nil {
326+
if err := writeJSONResponse(w, verifyResponse{Decision: decision}); err != nil {
359327
log.Printf("failed to encode verify response: %v", err)
360328
}
361329
}
@@ -418,7 +386,7 @@ func (s *Server) envoyAuthHandler(w http.ResponseWriter, r *http.Request) {
418386
"device_id": deviceID,
419387
"session_id": middleware.GetReqID(r.Context()),
420388
}
421-
if err := json.NewEncoder(w).Encode(response); err != nil {
389+
if err := writeJSONResponse(w, response); err != nil {
422390
log.Printf("failed to encode envoy auth response: %v", err)
423391
}
424392
default:
@@ -663,7 +631,7 @@ func (s *Server) deviceCertHandler(w http.ResponseWriter, r *http.Request) {
663631
return
664632
}
665633

666-
if err := json.NewEncoder(w).Encode(map[string]any{"certificate": string(certPEM)}); err != nil {
634+
if err := writeJSONResponse(w, map[string]any{"certificate": string(certPEM)}); err != nil {
667635
log.Printf("failed to encode device cert response: %v", err)
668636
}
669637
}
@@ -829,9 +797,8 @@ func (s *Server) tailscaleStatusHandler(w http.ResponseWriter, r *http.Request)
829797
}
830798

831799
status := s.getTailscaleInfo()
832-
w.Header().Set(contentTypeHeader, applicationJSON)
833800
w.WriteHeader(http.StatusOK)
834-
if err := json.NewEncoder(w).Encode(status); err != nil {
801+
if err := writeJSONResponse(w, status); err != nil {
835802
log.Printf("failed to encode tailscale status: %v", err)
836803
}
837804
}
@@ -1009,3 +976,46 @@ func (s *Server) validateBearerToken(ctx context.Context, authHeader string) (ma
1009976
tok := strings.TrimSpace(strings.TrimPrefix(authHeader, prefix))
1010977
return token.VerifyGoogleJWT(ctx, tok, s.cfg.GoogleClientID)
1011978
}
979+
980+
// setupRouter configures the chi router with middleware and routes
981+
func (s *Server) setupRouter() chi.Router {
982+
r := chi.NewRouter()
983+
telemetry.InstrumentRouter(r, "authz")
984+
985+
// Add middleware
986+
r.Use(middleware.RequestID)
987+
r.Use(s.loggingMiddleware)
988+
r.Use(s.metricsMiddleware)
989+
r.Use(middleware.Recoverer)
990+
r.Use(middleware.Timeout(defaultReadTimeout))
991+
992+
// Health and metrics endpoints
993+
r.Get("/health", s.healthHandler)
994+
r.Get("/metrics", promhttp.Handler().ServeHTTP)
995+
996+
// API routes
997+
r.Route("/v1", func(r chi.Router) {
998+
r.Route("/auth", func(r chi.Router) {
999+
r.Post("/verify", s.verifyHandler)
1000+
r.Post("/check", s.envoyAuthHandler)
1001+
r.Post("/mfa/verify-envoy", s.mfaVerifyHandler)
1002+
})
1003+
1004+
r.Route("/certs", func(r chi.Router) {
1005+
r.Post("/device", s.deviceCertHandler)
1006+
r.Get("/ca", s.caHandler)
1007+
})
1008+
1009+
r.Route("/tailscale", func(r chi.Router) {
1010+
r.Get("/status", s.tailscaleStatusHandler)
1011+
})
1012+
})
1013+
1014+
return r
1015+
}
1016+
1017+
// writeJSONResponse writes a JSON response with proper headers
1018+
func writeJSONResponse(w http.ResponseWriter, data interface{}) error {
1019+
w.Header().Set(contentTypeHeader, applicationJSON)
1020+
return json.NewEncoder(w).Encode(data)
1021+
}

0 commit comments

Comments
 (0)