Upgrading to v2.2.x
2.2.0โ
Applies to: Upgrading from v2.0.x or v2.1.x to v2.2.x
Version 2.2.0 introduces first-class integration of the standalone HealthzServer into ExpressServer. This replaces the legacy Express-mounted health check routes with dedicated, isolated Kubernetes health probe endpoints (/healthz, /readyz, /startupz) running on a dedicated port (default 8282), avoiding probe timeouts caused by application event-loop load or request queue saturation.
๐ฏ Quick Summaryโ
- Primary Change:
ExpressServerno longer mounts/healthzdirectly onto the Express application. Health probes are now managed via the dedicatedHealthzServeron an isolated port (default8282). - Configuration Update:
withHealthCheck()andconfig.healthCheckare replaced withenableHealthzServer()/withHealthzServer()andconfig.healthzServer. - Readiness Probes:
server.registerHealthCheck(name, fn, options)now maps checks toHealthzServerprobes, defaulting to the'readiness'probe. - Synchronous Readiness Query:
server.ready()is now a synchronous boolean method (along withserver.isReady()), reflecting whether the service is accepting traffic. - Estimated migration time: 5-10 minutes.
โ ๏ธ Breaking Changes & Migrationsโ
1. ServerConfigBuilder Methodsโ
The legacy .withHealthCheck() method has been replaced with dedicated Healthz server configuration helpers:
// Old (v2.0 / v2.1)
const config = new ServerConfigBuilder()
.withPort(3000)
.withHealthCheck({ path: '/healthz', detailed: true })
.build();
// New (v2.2.0+)
const config = new ServerConfigBuilder()
.withPort(3000)
.enableHealthzServer({ port: 8282 })
// or: .withHealthzServer({ port: 8282, shutdownDelayMs: 5000 })
.build();
To disable the Healthz probe server:
// Old
builder.disableHealthCheck();
// New
builder.disableHealthzServer();
2. Express Server Health Route Removalโ
ExpressServer no longer exposes a /healthz route on the main application port. If your Kubernetes deployments, Docker compose setups, or load balancers were probing http://localhost:3000/healthz, update your probe configurations to target the dedicated Healthz probe port:
# Old Kubernetes probe configuration (on app port 3000)
livenessProbe:
httpGet:
path: /healthz
port: 3000
# New Kubernetes probe configuration (on healthz port 8282)
livenessProbe:
httpGet:
path: /healthz
port: 8282
readinessProbe:
httpGet:
path: /readyz
port: 8282
startupProbe:
httpGet:
path: /startupz
port: 8282
3. Server Configuration Object (CatbeeServerConfig)โ
The healthCheck property and skipHealthzChecksValidation have been removed from CatbeeServerConfig and replaced with healthzServer:
// Old (v2.0 / v2.1)
const server = new ExpressServer({
port: 3000,
healthCheck: {
path: '/healthz',
detailed: true
}
});
// New (v2.2.0+)
const server = new ExpressServer({
port: 3000,
healthzServer: {
enable: true,
port: 8282,
shutdownDelayMs: 5000
}
});
4. server.registerHealthCheck() Enhancementsโ
registerHealthCheck() now accepts target probe options ('readiness', 'liveness', or 'both', defaulting to 'readiness'), and check functions receive an optional AbortSignal:
// Old
server.registerHealthCheck('db', async () => await checkDb());
// New
server.registerHealthCheck('db', async (signal) => {
return await db.ping({ signal });
}, 'readiness'); // Defaults to 'readiness'
5. server.ready() is Synchronousโ
server.ready() previously executed health checks asynchronously and returned Promise<boolean>. In v2.2.0, server.ready() synchronously returns the current readiness flag (boolean) matching server.isReady():
// Old
const isReady = await server.ready();
// New
const isReady = server.ready(); // or server.isReady()
6. Environment Variablesโ
The legacy server-level health check environment variables have been replaced with dedicated Healthz server environment variables:
| Old Variable | New Variable / Replacement |
|---|---|
SERVER_HEALTH_CHECK_PATH | HEALTHZ_PATH (fallback: SERVER_HEALTHZ_PATH) |
SERVER_HEALTH_CHECK_DETAILED_OUTPUT | HEALTHZ_DETAILED (fallback: SERVER_HEALTHZ_DETAILED) |
SERVER_HEALTH_CHECK_WITH_GLOBAL_PREFIX | (Removed; HealthzServer runs on its own port and does not use route prefix) |
SERVER_SKIP_HEALTHZ_CHECKS_VALIDATION | (Removed; control readiness via server.setReady() or readiness probe config) |
| (None) | SERVER_HEALTHZ_ENABLE or HEALTHZ_ENABLE (toggle HealthzServer in ExpressServer) |
| (None) | HEALTHZ_PORT or SERVER_HEALTHZ_PORT (dedicated probe server port) |
| (None) | HEALTHZ_READYZ_PATH or SERVER_READYZ_PATH (default /readyz) |
| (None) | HEALTHZ_STARTUPZ_PATH or SERVER_STARTUPZ_PATH (default /startupz) |
| (None) | HEALTHZ_SHUTDOWN_DELAY_MS or SERVER_HEALTHZ_SHUTDOWN_DELAY_MS (LB drain delay) |
| (None) | HEALTHZ_CHECK_TIMEOUT_MS or SERVER_HEALTHZ_CHECK_TIMEOUT_MS (check timeout) |
7. Decoupled Startup State & Pre-binding Probe Bootโ
- Probe Server Starts Before Listen:
HealthzServerbegins listening on its port before Express binds or runsbeforeStarthooks, allowing/healthzto return200 OKwhile/startupzand/readyzaccurately return503 Service Unavailable. - Decoupled Startup State:
/startupzreturns503 Service Unavailableuntil application startup completes.ExpressServerautomatically invokesserver.markStartupComplete()once listening. - Probe Resilience: When service readiness transitions to
false(during graceful shutdown draining or temporary dependency outages),startupCompleteremainstrueand/startupzstays200 OK, preventing Kubernetes from triggering startup probe failures or kill loops. - Method Renames:
HealthzServer.isStarted()has been replaced byHealthzServer.isRunning(). New methodsmarkStartupComplete()andisStartupComplete()are available on bothHealthzServerandExpressServer.