server

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 23, 2026 License: MIT Imports: 18 Imported by: 0

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

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

func RequestIDFromContext(ctx context.Context) string

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>"}.

func WriteJSON

func WriteJSON(w http.ResponseWriter, status int, v any) error

WriteJSON encodes v as JSON and writes it to w with the given status code. It sets Content-Type to application/json.

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

type Middleware func(http.Handler) http.Handler

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

func Defaults(logger *slog.Logger) []Option

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 WithAddr

func WithAddr(addr string) Option

WithAddr sets the listen address. Default is ":8080".

func WithIdleTimeout

func WithIdleTimeout(d time.Duration) Option

WithIdleTimeout sets the maximum amount of time to wait for the next request when keep-alives are enabled.

func WithLogger

func WithLogger(l *slog.Logger) Option

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

func WithReadHeaderTimeout(d time.Duration) Option

WithReadHeaderTimeout sets the maximum duration for reading request headers.

func WithReadTimeout

func WithReadTimeout(d time.Duration) Option

WithReadTimeout sets the maximum duration for reading the entire request.

func WithShutdownTimeout

func WithShutdownTimeout(d time.Duration) Option

WithShutdownTimeout sets the maximum duration to wait for active connections to close during graceful shutdown. Default is 15 seconds.

func WithWriteTimeout

func WithWriteTimeout(d time.Duration) Option

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

func (r *Router) Handle(pattern string, handler http.Handler)

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.

func (*Router) Mount

func (r *Router) Mount(prefix string, handler http.Handler)

Mount attaches an http.Handler under the given prefix. All requests starting with prefix are forwarded to the handler with the prefix stripped.

func (*Router) ServeHTTP

func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP implements http.Handler, making Router usable as a handler.

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

func New(handler http.Handler, opts ...Option) *Server

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

func (s *Server) Addr() string

Addr returns the listener address after the server has started. Returns an empty string if the server has not started yet.

func (*Server) ListenAndServe

func (s *Server) ListenAndServe() error

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

func (s *Server) ListenAndServeTLS(certFile, keyFile string) error

ListenAndServeTLS starts the server with TLS and blocks until a signal is received.

func (*Server) Shutdown

func (s *Server) Shutdown(ctx context.Context) error

Shutdown gracefully shuts down the server. It calls any registered onShutdown hooks, then waits for active connections to drain within the shutdown timeout.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL