Add production-ready HTTP server package with routing, health checks, and middleware
Introduces server/ sub-package as the server-side companion to the existing Client. Includes Router (over http.ServeMux with groups and mounting), graceful shutdown with signal handling, health endpoints (/healthz, /readyz), and built-in middlewares (RequestID, Recovery, Logging). Zero external dependencies. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
55
server/health.go
Normal file
55
server/health.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// ReadinessChecker is a function that reports whether a dependency is ready.
|
||||
// Return nil if healthy, or an error describing the problem.
|
||||
type ReadinessChecker func() error
|
||||
|
||||
// HealthHandler returns an http.Handler that exposes liveness and readiness
|
||||
// endpoints:
|
||||
//
|
||||
// - GET /healthz — liveness check, always returns 200 OK
|
||||
// - GET /readyz — readiness check, returns 200 if all checkers pass, 503 otherwise
|
||||
func HealthHandler(checkers ...ReadinessChecker) http.Handler {
|
||||
mux := http.NewServeMux()
|
||||
|
||||
mux.HandleFunc("GET /healthz", func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_ = json.NewEncoder(w).Encode(healthResponse{Status: "ok"})
|
||||
})
|
||||
|
||||
mux.HandleFunc("GET /readyz", func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
var errs []string
|
||||
for _, check := range checkers {
|
||||
if err := check(); err != nil {
|
||||
errs = append(errs, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
_ = json.NewEncoder(w).Encode(healthResponse{
|
||||
Status: "unavailable",
|
||||
Errors: errs,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_ = json.NewEncoder(w).Encode(healthResponse{Status: "ok"})
|
||||
})
|
||||
|
||||
return mux
|
||||
}
|
||||
|
||||
type healthResponse struct {
|
||||
Status string `json:"status"`
|
||||
Errors []string `json:"errors,omitempty"`
|
||||
}
|
||||
Reference in New Issue
Block a user