Skip to content

About

Simple Golang http server with graceful shutdown

Resources

Stars

2 stars

Watchers

1 watching

Forks

Latest commit

 

History

19 Commits

Folders and files

Repository files navigation

httpserver

A small HTTP server wrapper for Go with Kubernetes-native health probes and graceful shutdown. It wraps net/http.Server, adds /livez and /readyz endpoints, and drains connections cleanly on SIGINT/SIGTERM.

The server is written in Lisette (in src/) and compiled to Go. The generated Go package lives at the repo root, so other Go projects use it like any normal library.

Note: this library does not handle routing. Bring your own router (chi, gorilla/mux, http.ServeMux, …) and pass it via WithHandler.

Install

go get github.com/banan-tech/httpserver

Quick start

package main

import (
	"net/http"

	"github.com/banan-tech/httpserver"
)

func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("Hello, World"))
	})

	srv := httpserver.New([]httpserver.ServerOption{
		httpserver.WithHandler(mux),
		httpserver.WithAddr(":8080"),
	})

	// Run blocks until SIGINT/SIGTERM, then shuts down gracefully.
	if err := srv.Run(); err != nil {
		panic(err)
	}
}

Endpoints

Registered automatically unless WithoutDefaultProbes() is used. The probe paths default to /livez and /readyz and are configurable via WithLivenessPath / WithReadinessPath. Probes are mounted directly on the internal mux, so they never pass through (and are never logged by) the handler given to WithHandler:

Path Purpose
/livez Liveness — static 200 while the process can serve. No dependency checks (restart only).
/readyz Readiness — 200 when ready and all checks pass; 503 while shutting down or on failure.
/_metrics Only if WithMetricsHandler is set (e.g. Prometheus).
/ Your handler, if provided via WithHandler.

A failing readiness check returns 503 with a JSON body naming the check:

{ "failed_check": "db", "error": "connection refused" }

Options

Pass any of these to New:

Option Default Description
WithAddr(addr) :8080 Listen address.
WithPortFromEnv() — Use :$PORT if PORT is set (applied before options).
WithHandler(h) — Root handler mounted at /.
WithMetricsHandler(h) — Handler mounted at /_metrics.
WithReadinessCheck(name, fn) — Register a named dependency check for /readyz (call once per dependency).
WithoutDefaultProbes() off Disable the built-in liveness and readiness probes.
WithLivenessPath(path) /livez Path the liveness probe is mounted at.
WithReadinessPath(path) /readyz Path the readiness probe is mounted at.
WithLogger(l) JSON Structured *slog.Logger.
WithReadHeaderTimeout(d) 5s Header read deadline (Slowloris protection).
WithReadTimeout(d) 15s Full request read deadline.
WithWriteTimeout(d) 70s Response write deadline.
WithIdleTimeout(d) 90s Keep-alive idle timeout.
WithShutdownTimeout(d) 15s Graceful drain deadline.
WithShutdownHook(fn) — Run during shutdown, after connections drain.

Readiness checks

srv := httpserver.New([]httpserver.ServerOption{
	httpserver.WithHandler(mux),
	httpserver.WithReadinessCheck("db", func(ctx context.Context) error {
		return db.PingContext(ctx)
	}),
})

Graceful shutdown

On SIGINT/SIGTERM, Run flips the readiness probe to 503 (so Kubernetes stops routing new traffic), then drains in-flight requests within ShutdownTimeout before running any shutdown hooks and exiting.

Keep ShutdownTimeout below the pod's terminationGracePeriodSeconds, or SIGKILL fires before the drain finishes. Default: 15s < 30s (the Kubernetes default).

Server API

Method Description
New(opts) Build a server from options.
Run() Serve, blocking until a signal, then shut down gracefully.
Start() Serve, blocking (no signal handling). A clean stop returns nil.
Shutdown(ctx) Drain connections within the shutdown timeout, then run hooks.
Handler() The root http.Handler, handy for httptest.

Development

The source of truth is the Lisette code in src/. The root .go files are generated — do not edit them by hand.

lis run            # run the example (src/main.lis)
lis check          # type-check
make emit          # compile src/ to Go and emit the package into the repo root

About

Simple Golang http server with graceful shutdown

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages