Overview

Provide health check endpoints for load balancers and Kubernetes. Essential for production deployments.

Features

  • Liveness probe (/health/live)
  • Readiness probe (/health/ready)
  • Dependency checks
  • JSON status response

Installation

npx hanma add health-check

Code

import { Router, Request, Response } from 'express';

const router = Router();

interface HealthCheckResult {
  status: 'healthy' | 'unhealthy';
  timestamp: string;
  uptime: number;
  checks?: Record<string, CheckResult>;
}

interface CheckResult {
  status: 'pass' | 'fail';
  latency?: number;
  message?: string;
}

/**
 * Register health check functions
 * Add your database, cache, external service checks here
 */
const healthChecks: Record<string, () => Promise<CheckResult>> = {
  // Example: Database check
  // database: async () => {
  //   const start = Date.now();
  //   try {
  //     await prisma.$queryRaw`SELECT 1`;
  //     return { status: 'pass', latency: Date.now() - start };
  //   } catch (e) {
  //     return { status: 'fail', message: (e as Error).message };
  //   }
  // },
  
  // Example: Redis check
  // redis: async () => {
  //   const start = Date.now();
  //   try {
  //     await redis.ping();
  //     return { status: 'pass', latency: Date.now() - start };
  //   } catch (e) {
  //     return { status: 'fail', message: (e as Error).message };
  //   }
  // },
};

/**
 * Run all health checks
 */
const runHealthChecks = async (): Promise<HealthCheckResult> => {
  const checks: Record<string, CheckResult> = {};
  let allHealthy = true;

  for (const [name, check] of Object.entries(healthChecks)) {
    try {
      checks[name] = await check();
      if (checks[name].status === 'fail') {
        allHealthy = false;
      }
    } catch (error) {
      checks[name] = { status: 'fail', message: (error as Error).message };
      allHealthy = false;
    }
  }

  return {
    status: allHealthy ? 'healthy' : 'unhealthy',
    timestamp: new Date().toISOString(),
    uptime: process.uptime(),
    checks: Object.keys(checks).length > 0 ? checks : undefined,
  };
};

/**
 * GET /health
 * Basic health check - returns 200 if server is responding
 * Use for load balancer health probes
 */
router.get('/health', (_req: Request, res: Response) => {
  res.status(200).json({
    status: 'healthy',
    timestamp: new Date().toISOString(),
  });
});

/**
 * GET /health/live
 * Liveness probe - is the server running?
 * Returns 200 if process is alive
 */
router.get('/health/live', (_req: Request, res: Response) => {
  res.status(200).json({
    status: 'alive',
    uptime: process.uptime(),
  });
});

/**
 * GET /health/ready
 * Readiness probe - is the server ready to accept traffic?
 * Checks all dependencies (database, cache, etc.)
 */
router.get('/health/ready', async (_req: Request, res: Response) => {
  const result = await runHealthChecks();
  const statusCode = result.status === 'healthy' ? 200 : 503;
  res.status(statusCode).json(result);
});

/**
 * GET /health/detailed
 * Detailed health check with all dependency statuses
 * Protected in production (add auth middleware if needed)
 */
router.get('/health/detailed', async (_req: Request, res: Response) => {
  const result = await runHealthChecks();
  
  res.status(result.status === 'healthy' ? 200 : 503).json({
    ...result,
    version: process.env.npm_package_version || 'unknown',
    environment: process.env.NODE_ENV || 'development',
    memory: {
      used: Math.round(process.memoryUsage().heapUsed / 1024 / 1024),
      total: Math.round(process.memoryUsage().heapTotal / 1024 / 1024),
      unit: 'MB',
    },
  });
});

export default router;

Usage

import { healthRoutes } from './routes/health-check';

app.use('/health', healthRoutes);

// GET /health/live - Returns 200 if server is running
// GET /health/ready - Returns 200 if dependencies are ready

Dependencies

No external dependencies required.

Frequently Asked Questions

How do I install Health Check Routes?
Run the following command: npx hanma add health-check
How do I use this snippet?
Copy the code and paste it into your project. The snippet will be saved to routes/health-check.ts.
Can I customize this snippet?
Yes! All snippets are copy-paste code that you own. Feel free to modify them to fit your needs.
Does this work with other frameworks?
This snippet is designed for the specific framework. Check the other framework pages for equivalent implementations.