// Package server provides a lifecycle-aware HTTP server for Einherjar services. // // [Server] embeds both [lifecycle.Component] and [chi.Router], so it plugs // directly into [launcher.New] and exposes the full chi routing API. // // For the happy path use [web.New], which pre-wires the recommended middleware // stack. Use this package directly when you need explicit control over // middleware order, a custom request-ID generator, or any other deviation from // the defaults. // // # Basic usage // // srv := server.New(logger, server.Config{Port: 8080}, // server.WithMiddleware( // mw.Recover(), // mw.RequestID(myIDGenerator), // mw.RequestLogger(logger), // mw.CORS([]string{"https://example.com"}), // ), // ) // // srv.Get("/health", health.NewHandler(logger, db)) // // lc := launcher.New(logger) // lc.Append(srv) // lc.BeforeStart(func() error { // srv.Mount("/v1", apiRouter) // return nil // }) // if err := lc.Run(); err != nil { // logger.Error("launcher failed", err) // os.Exit(1) // } // // # Lifecycle // // [Server.OnInit] applies registered middleware to the router. // [Server.OnStart] binds the TCP listener synchronously — a port conflict // surfaces immediately rather than silently dropping the server. Requests // are served in a background goroutine. // [Server.OnStop] performs a graceful shutdown within [Config.ShutdownTimeout]. // // # Environment variables // // EINHERJAR_SERVER_HOST=0.0.0.0 bind address (default 0.0.0.0) // EINHERJAR_SERVER_PORT=8080 listen port (default 8080) // EINHERJAR_SERVER_READ_TIMEOUT=5s HTTP read timeout (default 5s) // EINHERJAR_SERVER_WRITE_TIMEOUT=10s HTTP write timeout (default 10s) // EINHERJAR_SERVER_IDLE_TIMEOUT=120s keep-alive idle timeout (default 120s) // EINHERJAR_SERVER_SHUTDOWN_TIMEOUT=10s graceful shutdown budget (default 10s) package server