The HealthCheckEndpoint is a pre-built endpoint that provides a simple health check response for your REST API. This is useful for monitoring, load balancers, and orchestration systems that need to verify your service is running.
- Ready to Use: No configuration needed - just include it in your router
- System Information: Returns status, timestamp, uptime, and environment
- Customizable: Override the path or extend the response as needed
- Secure: Uses GET method with 200 OK status
import { BaseApiRouter, HealthCheckEndpoint } from 'api-machine';
class MyRouter extends BaseApiRouter {
override path = '/api';
async routes() {
return [
HealthCheckEndpoint, // Available at GET /api/health
// ... other endpoints
];
}
}{
"status": "ok",
"timestamp": "2025-11-08T12:00:00.000Z",
"uptime": 123.45,
"environment": "development"
}Response Fields:
status: Always "ok" when the server is respondingtimestamp: Current time in ISO 8601 formatuptime: Process uptime in secondsenvironment: Value ofNODE_ENVenvironment variable (defaults to "development")
Override the path to use a different endpoint URL:
class MyHealthCheck extends HealthCheckEndpoint {
override path = '/status'; // Available at GET /api/status
}Extend the endpoint to add custom health information:
import { HealthCheckEndpoint, ApiRequest, ApiResponse } from 'api-machine';
class ExtendedHealthCheck extends HealthCheckEndpoint {
override path = '/health';
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async handle(_request: ApiRequest, _response: ApiResponse) {
const baseHealth = await super.handle(_request, _response);
return {
...baseHealth,
version: '1.0.0',
database: await this.checkDatabase(),
cache: await this.checkCache(),
};
}
private async checkDatabase(): Promise<string> {
// Check database connection
return 'connected';
}
private async checkCache(): Promise<string> {
// Check cache connection
return 'connected';
}
}Replace the entire response with your own health check logic:
class CustomHealthCheck extends HealthCheckEndpoint {
override path = '/health';
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async handle(_request: ApiRequest, response: ApiResponse) {
const isHealthy = await this.performHealthChecks();
if (!isHealthy) {
response.status(503); // Service Unavailable
return {
status: 'unhealthy',
timestamp: new Date().toISOString(),
};
}
return {
status: 'healthy',
timestamp: new Date().toISOString(),
checks: {
database: 'ok',
cache: 'ok',
api: 'ok',
},
};
}
private async performHealthChecks(): Promise<boolean> {
// Implement your health check logic
return true;
}
}Configure your load balancer to poll the health check endpoint:
curl http://localhost:3000/api/healthUse the health check endpoint for liveness and readiness probes:
livenessProbe:
httpGet:
path: /api/health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /api/health
port: 3000
initialDelaySeconds: 5
periodSeconds: 5Add a health check to your Dockerfile:
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/api/health || exit 1Use monitoring tools to track service availability:
# Prometheus
curl http://localhost:3000/api/health | jq '.status'
# Nagios, Zabbix, etc.
check_http -H localhost -p 3000 -u /api/health -s "ok"- Keep it Simple: The health check should be fast and lightweight
- Status Codes: Return 200 for healthy, 503 for unhealthy
- Minimal Dependencies: Avoid complex checks that might fail unnecessarily
- Separate Readiness: Consider separate endpoints for liveness vs readiness
- Authentication: Health checks typically don't require authentication
class HealthRouter extends BaseApiRouter {
override path = '/';
async routes() {
return [
// Basic health check
HealthCheckEndpoint, // GET /health
// Detailed health with dependencies
class extends HealthCheckEndpoint {
override path = '/health/detailed';
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async handle(_request: ApiRequest, _response: ApiResponse) {
return {
status: 'ok',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
environment: process.env['NODE_ENV'] || 'development',
dependencies: {
database: 'connected',
redis: 'connected',
api: 'reachable',
},
};
}
},
// Liveness probe (is the service running?)
class extends HealthCheckEndpoint {
override path = '/health/live';
},
// Readiness probe (is the service ready to accept traffic?)
class extends HealthCheckEndpoint {
override path = '/health/ready';
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async handle(_request: ApiRequest, response: ApiResponse) {
const isReady = await this.checkReadiness();
if (!isReady) {
response.status(503);
return { status: 'not ready' };
}
return {
status: 'ready',
timestamp: new Date().toISOString(),
};
}
private async checkReadiness(): Promise<boolean> {
// Check if dependencies are ready
return true;
}
},
];
}
}- Quick Start Example - Includes HealthCheckEndpoint usage
- Complete Example - Advanced endpoint patterns
- HTTP Errors - Error handling for health checks