readiness

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Jul 18, 2026 License: MIT Imports: 2 Imported by: 0

Documentation

Overview

Package readiness provides a readiness-probe endpoint for the express framework. It exposes a single well-known path (defaulting to "/readyz") that answers 200 "ready" when the application reports itself ready to serve traffic and 503 "not ready" otherwise; requests to any other path are left untouched and continue down the chain. It ports the readiness-gating concept that Node process managers such as terminus and lightship attach to an HTTP server, where an orchestrator (Kubernetes, a load balancer, a service mesh) polls the endpoint and only routes live traffic to instances that report themselves ready.

Use it to separate "the process is up" from "the process should receive requests." A server may be running yet still be warming a cache, replaying a migration, draining connections before shutdown, or waiting on a downstream dependency; during those windows the readiness probe should fail so the orchestrator holds traffic back without killing the pod (that is the job of a separate liveness probe). Because the Ready callback is evaluated on every probe, the same endpoint reflects the current state and flips back to 200 the moment the application recovers, which the tests exercise directly.

Mechanically the middleware inspects req.Path() first. When the path does not match the configured Path it calls next() immediately and reads or writes nothing else, so it is safe to register globally via app.Use at the top of the chain ahead of routers and other middleware. When the path matches it short-circuits the chain: it invokes the Ready function and writes the response itself with res.Status(...).Send(...), never calling next(). It does not consult any request headers and emits a plain-text body, so it is deliberately dependency-free and cheap to call at a high probe frequency.

The behavior is governed by two options with sensible defaults. Path defaults to "/readyz" when left empty. Ready defaults to a function that always returns true when nil, so a zero-value Options yields an endpoint that is always ready — useful as a liveness-style stub. A ready probe returns HTTP 200 with the body "ready"; a failing probe returns HTTP 503 Service Unavailable with the body "not ready", the conventional signal that tells an orchestrator to stop sending traffic without treating the instance as dead. There is no allowance for HTTP method: any method hitting the path is probed, mirroring the permissive behavior of typical probe endpoints.

Parity with the Node originals is behavioral rather than structural. Libraries like terminus and lightship expose richer machinery — multiple named checks, graceful-shutdown hooks, signal handling, and JSON health documents — whereas this package distills the piece that matters for request gating: a single boolean predicate mapped onto 200/503 at a configurable path. Callers that need composite checks can aggregate them inside their own Ready function, keeping this middleware a thin, allocation-free adapter over the express handler signature.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func New

func New(opts ...Options) express.Handler

New returns readiness middleware configured by opts.

Example

ExampleNew wires the readiness probe into an application and drives it with httptest to show how the endpoint reflects application state. The middleware is registered globally via app.Use so it runs ahead of the router, and a closure-captured flag stands in for whatever real signal (cache warmed, migrations done) would gate traffic. The first probe is issued while the application reports itself not ready and therefore returns 503; the flag is then flipped and a second probe returns 200. Requests to other paths, such as "/", bypass the probe entirely and reach the normal route. The status codes and bodies are fully deterministic, so the example verifies them with an Output block.

package main

import (
	"fmt"
	"net/http/httptest"

	"github.com/malcolmston/express"
	"github.com/malcolmston/express/middleware/readiness"
)

func main() {
	ready := false

	app := express.New()
	app.Use(readiness.New(readiness.Options{
		Path:  "/readyz",
		Ready: func() bool { return ready },
	}))
	app.Get("/", func(req *express.Request, res *express.Response, next express.Next) {
		res.Send("home")
	})

	probe := func() (int, string) {
		rec := httptest.NewRecorder()
		req := httptest.NewRequest("GET", "/readyz", nil)
		app.ServeHTTP(rec, req)
		return rec.Code, rec.Body.String()
	}

	code, body := probe()
	fmt.Printf("before: %d %s\n", code, body)

	ready = true
	code, body = probe()
	fmt.Printf("after: %d %s\n", code, body)

	rec := httptest.NewRecorder()
	app.ServeHTTP(rec, httptest.NewRequest("GET", "/", nil))
	fmt.Printf("route: %d %s\n", rec.Code, rec.Body.String())

}
Output:
before: 503 not ready
after: 200 ready
route: 200 home

Types

type Options

type Options struct {
	// Ready reports whether the application is ready to serve traffic. When nil
	// the application is always considered ready.
	Ready func() bool
	// Path is the endpoint served. Defaults to "/readyz".
	Path string
}

Options configures the readiness middleware.

Jump to

Keyboard shortcuts

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