Documentation
¶
Overview ¶
Package webapi holds the HTTP API surface for registry-stats: the five Grafana-facing handlers (/api/health, /api/snapshot, /api/pulls, /api/pulls/daily, /api/summary), the lifecycle wiring (access log, graceful shutdown), and the pure filter/query helpers the handlers share.
Handlers depend only on the api.Store and api.HealthSignal interfaces. The composition root in main.go constructs concrete instances (*store.FS, *health.Marker) and passes them via Deps to New. This isolates the HTTP surface from persistence and healthcheck concerns so each can evolve independently.
Inviolate contract: the JSON response shapes, query parameter names, status codes, and defensive headers (X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Cache-Control) match the pre-refactor main.go surface byte-for-byte. Grafana dashboards and Loki alerts pinned on any of those remain compatible.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func New ¶
New constructs the HTTP server, wiring the handlers to the Deps and applying access-log middleware. Does not start the server; call Start (or ListenAndServe) separately so the composition root can emit a log line at the right moment.
func Shutdown ¶
Shutdown marks the service unhealthy (so the orchestrator stops routing traffic), then gracefully shuts down srv with a 5-second timeout. The timeout is derived from context.Background so it survives the outer shutdown ctx already having been cancelled by the signal that kicked off the shutdown.
cause is logged alongside the shutdown so Loki can distinguish SIGTERM, SIGINT, or an internal trigger. Pass context.Cause(parentCtx) when the caller already has the parent context in scope.
func Start ¶
Start launches srv.ListenAndServe in a new goroutine and returns a channel that receives the first fatal error (anything other than ErrServerClosed). The channel is closed without a send on normal shutdown. Callers select on the returned channel to detect bind failures and propagate them to the composition root.
func WithAccessLog ¶
WithAccessLog emits one structured log line per HTTP request, at DEBUG for 2xx/3xx (quiet by default; turn on LOG_LEVEL=debug to see them), WARN for 4xx, and ERROR for 5xx. This makes dashboard failures traceable in Loki without flooding logs for normal Grafana polls.
Types ¶
type Deps ¶
type Deps struct {
Store api.Store
Health api.HealthSignal
Logger *slog.Logger
ListenAddr string
EnableJSONAPI bool
EnableMetrics bool
}
Deps is the injection surface for the webapi package. Concrete implementations live elsewhere: Store is *store.FS from internal/store, Health is *health.Marker. A nil Logger falls back to slog.Default.