# Health Check API Integration This document describes the integration between the MaplePress frontend and the Health Check API endpoint. ## Table of Contents - [Overview](#overview) - [Backend API Specification](#backend-api-specification) - [Frontend Implementation](#frontend-implementation) - [Service Methods](#service-methods) - [Usage Examples](#usage-examples) - [Use Cases](#use-cases) - [Error Handling](#error-handling) - [Testing](#testing) - [Troubleshooting](#troubleshooting) --- ## Overview The Health Check API is a simple, unauthenticated endpoint that verifies the MaplePress backend service is running and operational. It's commonly used for: - **Monitoring**: Service availability checks - **Load Balancers**: Health probe endpoints - **Startup Verification**: Ensuring backend is ready before initializing frontend - **API Connectivity**: Testing network connectivity to backend ### Key Features - ✅ **No Authentication Required**: Public endpoint - ✅ **Simple Response**: Returns `{ "status": "healthy" }` - ✅ **Fast Response**: Lightweight check with minimal processing - ✅ **Always Available**: Does not depend on database or external services --- ## Backend API Specification ### Endpoint ``` GET /health ``` ### Authentication **None required** - This is a public endpoint. ### Request Headers No headers required. ### Request Parameters None. ### Response (200 OK) ```json { "status": "healthy" } ``` ### Response Fields | Field | Type | Description | |-------|------|-------------| | status | string | Health status - always "healthy" when service is running | ### Error Responses - `503 Service Unavailable`: Backend service is down or unreachable - Network errors: Connection refused, timeout, etc. ### Backend Implementation **Handler File**: `cloud/maplepress-backend/internal/interface/http/handler/healthcheck/healthcheck_handler.go` ```go func (h *Handler) Handle(w http.ResponseWriter, r *http.Request) { response := map[string]string{ "status": "healthy", } httpresponse.OK(w, response) } ``` --- ## Frontend Implementation ### Service File **Location**: `src/services/API/HealthService.js` ### Dependencies ```javascript import ApiClient from "./ApiClient"; ``` ### Architecture The HealthService follows the same three-layer architecture as other API services: ``` ┌─────────────────────────────────────┐ │ React Components (UI) │ │ - Dashboard, Status Indicators │ └─────────────┬───────────────────────┘ │ ↓ ┌─────────────────────────────────────┐ │ HealthService (API Layer) │ │ - checkHealth() │ │ - isHealthy() │ │ - waitUntilHealthy() │ │ - getDetailedStatus() │ └─────────────┬───────────────────────┘ │ ↓ ┌─────────────────────────────────────┐ │ ApiClient (HTTP Layer) │ │ - GET /health │ └─────────────┬───────────────────────┘ │ ↓ ┌─────────────────────────────────────┐ │ Backend API │ │ GET /health → { status: "healthy" }│ └─────────────────────────────────────┘ ``` --- ## Service Methods ### 1. `checkHealth()` Check if the backend service is healthy. **Signature**: ```javascript async function checkHealth(): Promise ``` **Returns**: ```javascript { status: "healthy" } ``` **Throws**: `Error` if service is unreachable or unhealthy **Example**: ```javascript import HealthService from './services/API/HealthService'; try { const health = await HealthService.checkHealth(); if (health.status === 'healthy') { console.log('✅ Backend is healthy'); } } catch (error) { console.error('❌ Backend is down:', error.message); } ``` --- ### 2. `isHealthy()` Simple boolean check for backend health. **Signature**: ```javascript async function isHealthy(): Promise ``` **Returns**: `true` if backend is healthy, `false` otherwise **Example**: ```javascript const healthy = await HealthService.isHealthy(); if (healthy) { console.log('✅ Backend is ready'); } else { console.error('❌ Backend is not available'); } ``` **Use Case**: Quick status checks, conditional rendering --- ### 3. `waitUntilHealthy()` Wait for the backend to become healthy (with retries). **Signature**: ```javascript async function waitUntilHealthy(options?: Object): Promise ``` **Parameters**: ```javascript { maxAttempts: number, // Maximum retry attempts (default: 30) retryDelayMs: number // Delay between attempts in ms (default: 1000) } ``` **Returns**: `true` if backend became healthy, `false` if timeout **Example**: ```javascript // Wait up to 10 seconds (10 attempts x 1 second) const ready = await HealthService.waitUntilHealthy({ maxAttempts: 10, retryDelayMs: 1000 }); if (ready) { console.log('✅ Backend is ready!'); // Proceed with app initialization } else { console.error('❌ Backend did not become ready in time'); // Show error message to user } ``` **Use Case**: Application startup, waiting for backend deployment --- ### 4. `getDetailedStatus()` Get detailed health status with timing information. **Signature**: ```javascript async function getDetailedStatus(): Promise ``` **Returns**: ```javascript { healthy: boolean, // Whether backend is healthy status: string, // "healthy" or "unhealthy" responseTimeMs: number, // Response time in milliseconds timestamp: Date, // When check was performed error?: string // Error message if unhealthy } ``` **Example**: ```javascript const status = await HealthService.getDetailedStatus(); console.log(`Backend Status: ${status.status}`); console.log(`Response Time: ${status.responseTimeMs}ms`); console.log(`Checked At: ${status.timestamp.toISOString()}`); if (!status.healthy) { console.error(`Error: ${status.error}`); } ``` **Use Case**: Monitoring dashboards, performance tracking, diagnostics --- ## Usage Examples ### Example 1: Application Startup Check Check backend health before initializing the app: ```javascript // In App.jsx or main.jsx import { useEffect, useState } from 'react'; import HealthService from './services/API/HealthService'; function App() { const [backendReady, setBackendReady] = useState(false); const [error, setError] = useState(null); useEffect(() => { async function checkBackend() { try { const healthy = await HealthService.isHealthy(); setBackendReady(healthy); if (!healthy) { setError('Backend service is not available'); } } catch (err) { setError(err.message); } } checkBackend(); }, []); if (error) { return
Backend Error: {error}
; } if (!backendReady) { return
Connecting to backend...
; } return
App content...
; } ``` --- ### Example 2: Status Indicator Component Show real-time backend status: ```javascript import { useEffect, useState } from 'react'; import HealthService from '../services/API/HealthService'; function BackendStatusIndicator() { const [status, setStatus] = useState(null); useEffect(() => { // Check status every 30 seconds const checkStatus = async () => { const detail = await HealthService.getDetailedStatus(); setStatus(detail); }; checkStatus(); const interval = setInterval(checkStatus, 30000); return () => clearInterval(interval); }, []); if (!status) { return Checking...; } return (
Backend: {status.status} ({status.responseTimeMs}ms)
); } ``` --- ### Example 3: Deployment Health Check Wait for backend after deployment: ```javascript import HealthService from './services/API/HealthService'; async function waitForBackend() { console.log('Waiting for backend to become ready...'); const ready = await HealthService.waitUntilHealthy({ maxAttempts: 60, // Wait up to 1 minute retryDelayMs: 1000 // Check every second }); if (ready) { console.log('✅ Backend is ready!'); return true; } else { console.error('❌ Backend deployment timeout'); return false; } } // Usage in deployment script if (await waitForBackend()) { // Proceed with app initialization } else { // Show deployment error message } ``` --- ### Example 4: Error Recovery Retry failed API calls after backend recovers: ```javascript import HealthService from './services/API/HealthService'; import SiteService from './services/API/SiteService'; async function fetchSitesWithRetry() { try { // Try to fetch sites const sites = await SiteService.listSites(); return sites; } catch (error) { console.error('Failed to fetch sites:', error); // Check if backend is healthy const healthy = await HealthService.isHealthy(); if (!healthy) { console.log('Backend is down, waiting for recovery...'); // Wait for backend to recover const recovered = await HealthService.waitUntilHealthy({ maxAttempts: 10, retryDelayMs: 2000 }); if (recovered) { console.log('Backend recovered, retrying...'); return await SiteService.listSites(); } } throw error; } } ``` --- ## Use Cases ### 1. **Monitoring & Observability** - Service uptime monitoring - Response time tracking - Health dashboard indicators - Alerting on service degradation ### 2. **Load Balancer Integration** - Health probe endpoint for AWS/Azure/GCP load balancers - Kubernetes liveness/readiness probes - Docker healthcheck configuration ### 3. **Application Lifecycle** - Startup health verification - Graceful degradation on backend issues - Post-deployment verification - Environment validation (dev/staging/prod) ### 4. **User Experience** - Show connection status to users - Prevent API calls when backend is down - Display maintenance mode messages - Automatic retry on recovery ### 5. **Development & Testing** - Verify backend is running before tests - E2E test prerequisites - Local development environment checks - CI/CD pipeline health gates --- ## Error Handling ### Network Errors ```javascript try { await HealthService.checkHealth(); } catch (error) { if (error.message.includes('network') || error.message.includes('fetch')) { // Network connectivity issue console.error('Cannot reach backend - check network'); } } ``` ### Service Unavailable ```javascript try { await HealthService.checkHealth(); } catch (error) { if (error.message.includes('503') || error.message.includes('unavailable')) { // Backend is down or restarting console.error('Backend service is unavailable'); } } ``` ### Timeout Handling ```javascript // With timeout wrapper async function checkHealthWithTimeout(timeoutMs = 5000) { const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error('Health check timeout')), timeoutMs) ); try { return await Promise.race([ HealthService.checkHealth(), timeoutPromise ]); } catch (error) { console.error('Health check failed or timed out:', error.message); return { status: 'unhealthy' }; } } ``` --- ## Testing ### Manual Testing 1. **Start the backend**: ```bash cd cloud/maplepress-backend task dev ``` 2. **Test with curl**: ```bash curl -X GET http://localhost:8000/health ``` Expected response: ```json { "status": "healthy" } ``` 3. **Test from frontend**: ```javascript // In browser console import HealthService from './services/API/HealthService.js'; const health = await HealthService.checkHealth(); console.log(health); // { status: "healthy" } ``` ### Automated Testing ```javascript // Example test (using Jest or Vitest) import HealthService from '../services/API/HealthService'; describe('HealthService', () => { it('should return healthy status when backend is up', async () => { const health = await HealthService.checkHealth(); expect(health.status).toBe('healthy'); }); it('should return true for isHealthy()', async () => { const healthy = await HealthService.isHealthy(); expect(healthy).toBe(true); }); it('should include response time in detailed status', async () => { const status = await HealthService.getDetailedStatus(); expect(status).toHaveProperty('responseTimeMs'); expect(status.responseTimeMs).toBeGreaterThan(0); }); }); ``` --- ## Troubleshooting ### Issue: "Unable to connect to backend service" **Symptoms**: Network or fetch errors **Solutions**: 1. Verify backend is running: `curl http://localhost:8000/health` 2. Check `VITE_API_BASE_URL` in `.env` file 3. Verify no CORS issues in browser console 4. Check firewall/network settings ### Issue: "Backend service is temporarily unavailable" **Symptoms**: 503 status code **Solutions**: 1. Backend may be starting up - wait a few seconds 2. Check backend logs: `docker logs mapleopentech_backend` 3. Verify backend services (Cassandra, Redis) are running 4. Restart backend: `task end && task dev` ### Issue: Health check timeout **Symptoms**: Slow or no response **Solutions**: 1. Check backend server load 2. Verify network latency 3. Check if backend is overloaded 4. Consider increasing timeout in `waitUntilHealthy()` ### Issue: Always returns unhealthy **Symptoms**: `isHealthy()` always returns false **Solutions**: 1. Check browser console for errors 2. Verify API base URL is correct 3. Check CORS configuration 4. Test endpoint directly with curl --- ## Best Practices ### 1. **Use During Initialization** Always check backend health during app startup: ```javascript useEffect(() => { HealthService.isHealthy().then(healthy => { if (!healthy) { showBackendError(); } }); }, []); ``` ### 2. **Periodic Health Checks** For long-running apps, check periodically: ```javascript // Every 5 minutes setInterval(async () => { const healthy = await HealthService.isHealthy(); updateStatusIndicator(healthy); }, 300000); ``` ### 3. **Handle Failures Gracefully** Don't throw errors to users - handle them gracefully: ```javascript const healthy = await HealthService.isHealthy().catch(() => false); if (!healthy) { showOfflineMode(); } ``` ### 4. **Log Response Times** Monitor performance over time: ```javascript const status = await HealthService.getDetailedStatus(); analytics.track('backend_health', { responseTime: status.responseTimeMs, healthy: status.healthy }); ``` --- ## Integration with Other Services The HealthService can be combined with other services for robust error handling: ```javascript import HealthService from './services/API/HealthService'; import AuthManager from './services/Manager/AuthManager'; async function safeLogin(email, password) { // Check backend health first const healthy = await HealthService.isHealthy(); if (!healthy) { throw new Error('Backend is currently unavailable. Please try again later.'); } // Proceed with login return await AuthManager.login({ email, password }); } ``` --- ## Summary The Health Check API provides a simple, reliable way to verify backend availability: - ✅ **Simple Integration**: One GET request, no auth required - ✅ **Multiple Helper Methods**: `checkHealth()`, `isHealthy()`, `waitUntilHealthy()`, `getDetailedStatus()` - ✅ **Error Handling**: Comprehensive error detection and user-friendly messages - ✅ **Flexible Usage**: Startup checks, monitoring, status indicators, deployment verification - ✅ **Production Ready**: Tested against backend implementation For questions or issues, refer to the [Troubleshooting](#troubleshooting) section or check the main [README](../../README.md). --- **Last Updated**: October 30, 2024 **Frontend Version**: 0.0.0 **Backend API Version**: 1.0.0