Docs / ArchitectureKit 1.0 / Guides / Checking Health over HTTP

Checking Health over HTTP

An orchestrator such as Kubernetes regularly asks an application whether it can serve requests, and whether it is alive. To answer both by the state of the projections, hand the runs started with StartProjection or StartTransactionalProjection over to the Readiness and Liveness functions, and serve the handlers they return on paths of your choice.

They list each projection by the name it was given with Named:

run := architecturekit.StartProjection(ctx, store, architecturekit.SubjectTree("/books"), catalogProjection,
  architecturekit.Named("catalog"),
)

mux.Handle("GET /ready", httpapi.Readiness(run))
mux.Handle("GET /live", httpapi.Liveness(run))

Note that a nil run, a run without a name, or two runs of the same name, make Readiness and Liveness panic.

Both answer with 200 OK or 503 Service Unavailable, depending on where the projections stand:

Projection Readiness Liveness
catches up for the first time 503 200
can not reach the database at the start 503 200
is live 200 200
reconnects after it has caught up 200 200
has stopped 503 503

The application is ready once every projection has caught up, since a half-built view answers wrongly. A projection that reconnects later on, for example because the database restarts, keeps it ready: its view is behind, but consistent, and every instance shares the database, so taking them all out would answer nothing instead of something that is behind. A projection that has stopped makes the application neither ready nor alive, since its view never changes again. The orchestrator then restarts the application, which builds the view anew, with a configuration that may have been fixed in the meantime. There is no time limit for reconnecting, since a restart does not bring the database back.

The body of Readiness tells whether the application is ready, and where each projection stands:

{
  "isReady": true,
  "projections": {
    "catalog": {
      "phase": "live",
      "since": "2026-09-30T12:00:00Z",
      "hasCaughtUp": true,
      "attempts": 0,
      "revision": "42"
    }
  }
}

The body of Liveness has the same shape, but tells whether the application is alive, with isAlive instead of isReady.

Note that the body does not tell why a projection reconnects or has stopped, since health checks are usually reachable without signing in, and the reason may name internal addresses. Log it instead, for example by waiting for Done and calling Err.