Running the server
Wrap a router in a Server, tune the underlying transport with options, and shut down gracefully.
NewServer wraps a Router in a net/http.Server and gives it a Name, Start, Stop lifecycle. That contract is what a service registry calls, so the server drops into a supervised process without extra glue.
Starting and stopping
Config holds only the listen address. Start builds the address, logs the routes, and serves until Stop is called. It blocks, so run it in its own goroutine when the surrounding process has more to do.
srv := server.NewServer(server.Config{Host: "127.0.0.1", Port: 8080}, r, logger)
go func() {
if err := srv.Start(); err != nil {
log.Fatal("http server failed", "error", err)
}
}()
// on a shutdown signal, drain in-flight requests within the deadline.
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
_ = srv.Stop(ctx)Start returns nil on a clean shutdown. Stop calls the underlying Shutdown, which stops accepting new connections and waits for in-flight requests until ctx's deadline passes.
Tuning the transport
Everything beyond the listen address is set with functional options. NewServer applies a safe ReadHeaderTimeout default to guard against slow-header connections, then runs your options, so an option always overrides the default.
srv := server.NewServer(cfg, r, logger,
server.WithReadHeaderTimeout(5*time.Second),
server.WithReadTimeout(10*time.Second),
server.WithWriteTimeout(10*time.Second),
server.WithIdleTimeout(120*time.Second),
)WithReadHeaderTimeout(0) disables the header timeout, which is not recommended because it re-exposes the server to slow-header connections.
Reaching the raw server
For anything no option covers, HTTP returns the underlying *http.Server. Mutate it before Start, since changes after the server is serving have no effect.
srv.HTTP().TLSConfig = tlsConfig
srv.HTTP().ConnState = trackConnStateNote
The Logger argument is the minimal leveled interface the server writes to. It is satisfied structurally by github.com/toaweme/log, so pass that directly, or a null logger to discard output.