typescriptbeginner

Health Check Endpoint Pattern

Implement comprehensive health checks with dependency status, uptime, and readiness probes.

typescript
interface HealthCheck {
  name: string;
  check: () => Promise<{ status: 'healthy' | 'unhealthy'; latency: number; details?: string }>;
}

class HealthChecker {
  private checks: HealthCheck[] = [];
  private startTime = Date.now();

  register(name: string, check: () => Promise<void>): this {
    this.checks.push({
      name,
      check: async () => {
        const start = performance.now();
        try {
          await check();
          return { status: 'healthy', latency: Math.round(performance.now() - start) };
        } catch (err: any) {
          return { status: 'unhealthy', latency: Math.round(performance.now() - start), details: err.message };
        }
      },
    });
    return this;
  }

  async getHealth() {
    const results = await Promise.all(
      this.checks.map(async (c) => ({ name: c.name, ...await c.check() })),
    );
    const allHealthy = results.every(r => r.status === 'healthy');
    return {
      status: allHealthy ? 'healthy' : 'degraded',
      uptime: Math.round((Date.now() - this.startTime) / 1000),
      timestamp: new Date().toISOString(),
      version: process.env.APP_VERSION ?? '1.0.0',
      memory: {
        rss: `${(process.memoryUsage.rss() / 1e6).toFixed(1)}MB`,
        heap: `${(process.memoryUsage().heapUsed / 1e6).toFixed(1)}MB`,
      },
      checks: results,
    };
  }
}

// Usage
const health = new HealthChecker()
  .register('database', async () => {
    // await db.query('SELECT 1');
    await new Promise(r => setTimeout(r, 5)); // simulate
  })
  .register('redis', async () => {
    // await redis.ping();
    await new Promise(r => setTimeout(r, 2)); // simulate
  })
  .register('external-api', async () => {
    // await fetch('https://api.example.com/health');
    await new Promise(r => setTimeout(r, 50)); // simulate
  });

// Express route:
// app.get('/health', async (req, res) => {
//   const result = await health.getHealth();
//   res.status(result.status === 'healthy' ? 200 : 503).json(result);
// });

// Standalone test
health.getHealth().then(r => console.log(JSON.stringify(r, null, 2)));

Use Cases

  • Kubernetes liveness probes
  • Load balancer health checks
  • Service monitoring dashboards

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.