Detailed readiness handler — register against an INTERNAL or authenticated
route (e.g. a readyz endpoint reachable only from the cluster network or
behind auth). It exposes per-check states and details, which can reveal
internal topology and component information, so it must NOT be public. For
the public probe use LivenessHandler, which reports only the opaque
aggregate state.
$registry = (new HealthCheckRegistry())
->add(new DatabaseHealthCheck($pdo))
->add(new RedisHealthCheck($redis));
$app->get('/livez', new LivenessHandler($registry)); // public
$app->get('/readyz', new HealthCheckHandler($registry)) // internal
->middleware(AuthorizationMiddleware::class);
Response shape (RFC-health-json-inspired):
200 OK (everything up or degraded)
503 (any check is down)
{
"status": "up" | "degraded" | "down",
"checks": {
"database": {"state": "up", "detail": {"latencyMs": 1.2}},
"redis": {"state": "down", "detail": }}
}
}
A check that THROWS is treated as down. By default the raw exception class
and message are REDACTED from the response (they can carry DSNs, hostnames,
or credentials); pass includeErrorDetail: true only for a trusted internal
readiness route to surface the exception class and message. The handler
itself never throws.