Documentation
¶
Overview ¶
Package server provides a production-ready HTTP server with graceful shutdown, middleware composition, routing, and JSON response helpers.
Server ¶
Server wraps http.Server with net.Listener, signal-based graceful shutdown (SIGINT/SIGTERM), and lifecycle hooks. It is configured via functional options:
srv := server.New(handler,
server.WithAddr(":8080"),
server.Defaults(logger),
)
srv.ListenAndServe()
Router ¶
Router wraps http.ServeMux with middleware groups, prefix-based route groups, and sub-handler mounting. It supports Go 1.22+ method-based patterns:
r := server.NewRouter()
r.HandleFunc("GET /users/{id}", getUser)
api := r.Group("/api/v1", authMiddleware)
api.HandleFunc("GET /items", listItems)
Middleware ¶
Server middleware follows the func(http.Handler) http.Handler pattern. Available middleware: RequestID, Recovery, Logging, CORS, RateLimit, MaxBodySize, Timeout. Use Chain to compose them:
chain := server.Chain(server.RequestID(), server.Recovery(logger), server.Logging(logger))
Response helpers ¶
WriteJSON and WriteError provide JSON response writing with proper Content-Type headers.
Index ¶
- func HealthHandler(checkers ...ReadinessChecker) http.Handler
- func RequestIDFromContext(ctx context.Context) string
- func WriteError(w http.ResponseWriter, status int, msg string) error
- func WriteJSON(w http.ResponseWriter, status int, v any) error
- type CORSOption
- type Middleware
- func CORS(opts ...CORSOption) Middleware
- func Chain(mws ...Middleware) Middleware
- func Logging(logger *slog.Logger) Middleware
- func MaxBodySize(n int64) Middleware
- func RateLimit(opts ...RateLimitOption) Middleware
- func Recovery(opts ...RecoveryOption) Middleware
- func RequestID() Middleware
- func Timeout(d time.Duration) Middleware
- type Option
- func Defaults(logger *slog.Logger) []Option
- func WithAddr(addr string) Option
- func WithIdleTimeout(d time.Duration) Option
- func WithLogger(l *slog.Logger) Option
- func WithMiddleware(mws ...Middleware) Option
- func WithOnShutdown(fn func()) Option
- func WithReadHeaderTimeout(d time.Duration) Option
- func WithReadTimeout(d time.Duration) Option
- func WithShutdownTimeout(d time.Duration) Option
- func WithWriteTimeout(d time.Duration) Option
- type RateLimitOption
- type ReadinessChecker
- type RecoveryOption
- type Router
- func (r *Router) Group(prefix string, mws ...Middleware) *Router
- func (r *Router) Handle(pattern string, handler http.Handler)
- func (r *Router) HandleFunc(pattern string, fn http.HandlerFunc)
- func (r *Router) Mount(prefix string, handler http.Handler)
- func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)
- type RouterOption
- type Server
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func HealthHandler ¶
func HealthHandler(checkers ...ReadinessChecker) http.Handler
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 RequestIDFromContext ¶
RequestIDFromContext returns the request ID from the context, or an empty string if none is set.
func WriteError ¶
func WriteError(w http.ResponseWriter, status int, msg string) error
WriteError writes a JSON error response with the given status code and message. The response body is {"error": "<message>"}.
Types ¶
type CORSOption ¶
type CORSOption func(*corsOptions)
CORSOption configures the CORS middleware.
func AllowCredentials ¶
func AllowCredentials(allow bool) CORSOption
AllowCredentials indicates whether the response to the request can be exposed when the credentials flag is true.
func AllowHeaders ¶
func AllowHeaders(headers ...string) CORSOption
AllowHeaders sets the allowed request headers for preflight requests.
func AllowMethods ¶
func AllowMethods(methods ...string) CORSOption
AllowMethods sets the allowed HTTP methods for preflight requests. Default is GET, POST, HEAD.
func AllowOrigins ¶
func AllowOrigins(origins ...string) CORSOption
AllowOrigins sets the allowed origins. Use "*" to allow any origin. Default is no origins (CORS disabled).
func ExposeHeaders ¶
func ExposeHeaders(headers ...string) CORSOption
ExposeHeaders sets headers that browsers are allowed to access.
func MaxAge ¶
func MaxAge(seconds int) CORSOption
MaxAge sets the maximum time (in seconds) a preflight result can be cached.
type Middleware ¶
Middleware wraps an http.Handler to add behavior. This is the server-side counterpart of the client middleware type func(http.RoundTripper) http.RoundTripper.
func CORS ¶
func CORS(opts ...CORSOption) Middleware
CORS returns a middleware that handles Cross-Origin Resource Sharing. It processes preflight OPTIONS requests and sets the appropriate Access-Control-* response headers.
func Chain ¶
func Chain(mws ...Middleware) Middleware
Chain composes middlewares so that Chain(A, B, C)(handler) == A(B(C(handler))). Middlewares are applied from right to left: C wraps handler first, then B wraps the result, then A wraps last. This means A is the outermost layer and sees every request first.
func Logging ¶
func Logging(logger *slog.Logger) Middleware
Logging returns a middleware that logs each request's method, path, status code, duration, and request ID using the provided structured logger.
func MaxBodySize ¶
func MaxBodySize(n int64) Middleware
MaxBodySize returns a middleware that limits the size of incoming request bodies. If the body exceeds n bytes, the server returns 413 Request Entity Too Large. It wraps the body with http.MaxBytesReader.
func RateLimit ¶
func RateLimit(opts ...RateLimitOption) Middleware
RateLimit returns a middleware that limits requests using a per-key token bucket algorithm. When the limit is exceeded, it returns 429 Too Many Requests with a Retry-After header.
func Recovery ¶
func Recovery(opts ...RecoveryOption) Middleware
Recovery returns a middleware that recovers from panics in downstream handlers. A recovered panic results in a 500 Internal Server Error response and is logged (if a logger is configured) with the stack trace.
func RequestID ¶
func RequestID() Middleware
RequestID returns a middleware that assigns a unique request ID to each request. If the incoming request already has an X-Request-Id header, that value is used. Otherwise a new UUID v4 is generated via crypto/rand.
The request ID is stored in the request context (retrieve with RequestIDFromContext) and set on the response X-Request-Id header.
func Timeout ¶
func Timeout(d time.Duration) Middleware
Timeout returns a middleware that limits request processing time. If the handler does not complete within d, the client receives a 503 Service Unavailable response. It wraps http.TimeoutHandler.
type Option ¶
type Option func(*serverOptions)
Option configures a Server.
func Defaults ¶
Defaults returns a production-ready set of options including standard middleware (RequestID, Recovery, Logging), sensible timeouts, and the provided logger.
Middleware order: RequestID → Recovery → Logging → user handler.
func WithIdleTimeout ¶
WithIdleTimeout sets the maximum amount of time to wait for the next request when keep-alives are enabled.
func WithLogger ¶
WithLogger sets the structured logger used by the server for lifecycle events.
func WithMiddleware ¶
func WithMiddleware(mws ...Middleware) Option
WithMiddleware appends server middlewares to the chain. These are applied to the handler in the order given.
func WithOnShutdown ¶
func WithOnShutdown(fn func()) Option
WithOnShutdown registers a function to be called during graceful shutdown, before the HTTP server begins draining connections.
func WithReadHeaderTimeout ¶
WithReadHeaderTimeout sets the maximum duration for reading request headers.
func WithReadTimeout ¶
WithReadTimeout sets the maximum duration for reading the entire request.
func WithShutdownTimeout ¶
WithShutdownTimeout sets the maximum duration to wait for active connections to close during graceful shutdown. Default is 15 seconds.
func WithWriteTimeout ¶
WithWriteTimeout sets the maximum duration before timing out writes of the response.
type RateLimitOption ¶
type RateLimitOption func(*rateLimitOptions)
RateLimitOption configures the RateLimit middleware.
func WithBurst ¶
func WithBurst(n int) RateLimitOption
WithBurst sets the maximum burst size (bucket capacity).
func WithKeyFunc ¶
func WithKeyFunc(fn func(r *http.Request) string) RateLimitOption
WithKeyFunc sets a custom function to extract the rate-limit key from a request. By default, the client IP address is used.
func WithRate ¶
func WithRate(tokensPerSecond float64) RateLimitOption
WithRate sets the token refill rate (tokens per second).
type ReadinessChecker ¶
type ReadinessChecker func() error
ReadinessChecker is a function that reports whether a dependency is ready. Return nil if healthy, or an error describing the problem.
type RecoveryOption ¶
type RecoveryOption func(*recoveryOptions)
RecoveryOption configures the Recovery middleware.
func WithRecoveryLogger ¶
func WithRecoveryLogger(l *slog.Logger) RecoveryOption
WithRecoveryLogger sets the logger for the Recovery middleware. If not set, panics are recovered silently (500 is still returned).
type Router ¶
type Router struct {
// contains filtered or unexported fields
}
Router is a lightweight wrapper around http.ServeMux that adds middleware groups and sub-router mounting. It leverages Go 1.22+ enhanced patterns like "GET /users/{id}".
func NewRouter ¶
func NewRouter(opts ...RouterOption) *Router
NewRouter creates a new Router backed by a fresh http.ServeMux.
func (*Router) Group ¶
func (r *Router) Group(prefix string, mws ...Middleware) *Router
Group creates a sub-router with a shared prefix and optional middleware. Patterns registered on the group are prefixed automatically. The group shares the underlying ServeMux with the parent router.
Example:
api := router.Group("/api/v1", authMiddleware)
api.HandleFunc("GET /users", listUsers) // registers "GET /api/v1/users"
func (*Router) Handle ¶
Handle registers a handler for the given pattern. The pattern follows http.ServeMux conventions, including method-based patterns like "GET /users".
func (*Router) HandleFunc ¶
func (r *Router) HandleFunc(pattern string, fn http.HandlerFunc)
HandleFunc registers a handler function for the given pattern.
type RouterOption ¶
type RouterOption func(*Router)
RouterOption configures a Router.
func WithNotFoundHandler ¶
func WithNotFoundHandler(h http.Handler) RouterOption
WithNotFoundHandler sets a custom handler for requests that don't match any registered pattern. This is useful for returning JSON 404/405 responses instead of the default plain text.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is a production-ready HTTP server with graceful shutdown, middleware support, and signal handling.
func New ¶
New creates a new Server that will serve the given handler with the provided options. Middleware from options is applied to the handler.
func (*Server) Addr ¶
Addr returns the listener address after the server has started. Returns an empty string if the server has not started yet.
func (*Server) ListenAndServe ¶
ListenAndServe starts the server and blocks until a SIGINT or SIGTERM signal is received. It then performs a graceful shutdown within the configured shutdown timeout.
Returns nil on clean shutdown or an error if listen/shutdown fails.
func (*Server) ListenAndServeTLS ¶
ListenAndServeTLS starts the server with TLS and blocks until a signal is received.