httpserver

httpserver provides a configurable HTTP server bootstrap for Go services.

Part of nurago, a collection of independent Go packages for backend services.

import "github.com/tecnickcom/nurago/pkg/httpserver"

Package httpserver provides a configurable HTTP server bootstrap for Go services.

The package assembles the server from:

  • option-driven configuration (New + functional Options)
  • pluggable route binding via Binder
  • configurable default route set for operational endpoints
  • shared middleware application model
  • graceful shutdown orchestration via context and/or signal channel

Custom service routes are supplied by a Binder, while default routes can be enabled selectively (or all at once) through options.

Default Operational Routes

When enabled, the built-in route set includes:

  • /ip: returns the service public IP (via ipify integration)
  • /metrics: returns metrics payload (501 by default unless replaced)
  • /ping: liveness endpoint
  • /pprof/*option: pprof profiling endpoints
  • /status: service health endpoint
  • / (index): generated route index

Behavior

  • Lifecycle: non-blocking start, context-aware shutdown, configurable shutdown timeout, external wait-group and signal integration, abnormal-termination reporting via HTTPServer.ServeError, and ephemeral port discovery via HTTPServer.Addr.
  • Startup validation: misconfigured routes and options (nil handlers or middleware, duplicate or malformed routes, unknown default route identifiers) are reported by New as wrapped sentinel errors instead of panics.
  • Router defaults: not-found, method-not-allowed, and panic handlers with structured logging.
  • Middleware pipeline: common middleware (logger/timeout) plus global and per-route middleware composition, with per-route timeout override or opt-out (DisableTimeout).
  • Observability: trace-id propagation hooks, HTTP data redaction, per-request log entries carrying the response status code and size, optional pprof/metrics/status routes, and net/http internal diagnostics routed to the structured logger.
  • Transport: plain TCP or TLS (HTTP/1.1 and HTTP/2 via ALPN) from cert/key material (WithTLSCertData) or a custom WithTLSConfig.

Security

The default operational routes expose service internals: /pprof/*option serves runtime profiles (memory layout, goroutine stacks, CPU traces), the index route enumerates every registered endpoint, /metrics may reveal implementation details, and /ip performs an outbound call to a third-party service. Enable these routes only on internal or administrative listeners that are not reachable from the public internet, or protect them with authentication middleware appropriate for your environment.

For a usage example, refer to examples/service/internal/cli/bind.go.

When To Use

  • A service needs a server with sane timeouts, health endpoints, and pprof mounted correctly.
  • Shutdown must drain in-flight requests before the process exits.
  • You want the routing to stay httprouter, not a framework.

Example

ctx := context.Background()

srv, err := httpserver.New(
	ctx,
	&exampleBinder{},
	httpserver.WithServerAddr(":0"), // ephemeral port; see srv.Addr() for the actual address
	httpserver.WithEnableDefaultRoutes(httpserver.PingRoute, httpserver.StatusRoute),
	httpserver.WithRequestTimeout(30*time.Second),
	httpserver.WithShutdownTimeout(5*time.Second),
	httpserver.WithLogger(slog.New(slog.DiscardHandler)),
)
if err != nil {
	fmt.Println(err)
	return
}

// The server runs in the background; canceling ctx or calling Shutdown
// stops it gracefully.
srv.StartServer()

// ... serve traffic ...

err = srv.Shutdown(ctx)
if err != nil {
	fmt.Println(err)
	return
}

fmt.Println("server stopped")

// Output:
// server stopped

Full source is in example_httpserver_test.go. More runnable examples are on pkg.go.dev.

Dependencies

Importing this package pulls 1 external module:

  • github.com/julienschmidt/httprouter