# @unidev-hub/api-framework

A comprehensive TypeScript API framework for building robust microservices with Express that provides:

- 🚀 **Complete server initialization** with intelligent defaults
- 🔐 **Authentication** with Azure AD, JWT, or custom providers
- 📊 **Database connectivity** with PostgreSQL, MongoDB, or custom connectors
- 🏥 **Health checks** with Kubernetes-ready probes via @unidev-hub/health
- 📚 **OpenAPI documentation** with Swagger UI and ReDoc
- 🛡️ **Security** with Helmet, CORS, and rate limiting
- 🔄 **Standardized responses** with consistent formatting
- 🚫 **Error handling** with proper status codes and logging
- ✅ **Request validation** using Joi schemas
- 📈 **Metrics collection** for monitoring
- 🔍 **Correlation ID tracking** across microservices
- 🔄 **Lifecycle hooks** for customizing server startup and shutdown
- ⚙️ **Environment-specific configuration** with automatic detection
- 🔔 **Event system** for cross-component communication
- 🧩 **Plugin system** for extending functionality
- 📱 **Feature toggles** for controlled feature rollouts
- 🔄 **Circuit breakers** for resilient external service calls

## Installation

```bash
npm install @unidev-hub/api-framework --save
```

## Quick Start

Start a complete API service with just a few lines of code:

```typescript
// src/index.ts
import { startServer } from '@unidev-hub/api-framework';
import { setupRoutes } from './routes';

// Start the server with minimal configuration
startServer({
  serviceName: 'product-service',
  setupRoutes
}).catch((error) => {
  console.error('Failed to start service:', error);
  process.exit(1);
});

// src/routes/index.ts
import { Application, RequestHandler, Router } from 'express';
import { Logger } from '@unidev-hub/logger';
import { DatabaseConnection } from '@unidev-hub/database';

export async function setupRoutes(
  app: Application,
  dbConnection: DatabaseConnection | null, 
  authMiddleware: RequestHandler,
  logger: Logger
): Promise<void> {
  const router = Router();
  
  // Public routes
  router.get('/hello', (req, res) => {
    res.json({ message: 'Hello, World!' });
  });
  
  // Protected routes (requires authentication)
  router.get('/protected', authMiddleware, (req, res) => {
    res.json({ message: 'This is a protected endpoint', user: req.user });
  });
  
  // Mount routes to API base path
  app.use('/products', router);
  
  logger.info('Routes configured');
}
```

## Core Features

### Server Initialization

The framework provides a complete server initialization flow with smart defaults:

```typescript
import { startServer } from '@unidev-hub/api-framework';

// Start a server with more advanced options
startServer({
  serviceName: 'user-service',
  
  // Database configuration
  database: {
    type: 'postgres',
    connection: {
      host: process.env.DB_HOST,
      port: parseInt(process.env.DB_PORT || '5432'),
      username: process.env.DB_USER,
      password: process.env.DB_PASSWORD,
      database: process.env.DB_NAME
    }
  },
  
  // Authentication configuration
  auth: {
    type: 'jwt',
    jwt: {
      secret: process.env.JWT_SECRET,
      issuer: 'mycompany.com'
    }
  },
  
  // API settings
  api: {
    basePath: '/api/v1',
    cors: true,
    helmet: true,
    bodyLimit: '2mb'
  },
  
  // Routes setup
  setupRoutes
});
```

### Authentication

Multiple authentication strategies are supported out of the box:

```typescript
// JWT Authentication
auth: {
  type: 'jwt',
  jwt: {
    secret: process.env.JWT_SECRET,
    issuer: 'mycompany.com',
    audience: 'my-api'
  }
}

// Azure AD Authentication
auth: {
  type: 'azure',
  azure: {
    tenantId: process.env.AZURE_TENANT_ID,
    clientId: process.env.AZURE_CLIENT_ID,
    clientSecret: process.env.AZURE_CLIENT_SECRET,
    apiScope: 'api/.default'
  }
}

// No Authentication (for development)
auth: {
  type: 'none',
  required: false
}

// Custom Authentication
auth: {
  type: 'custom',
  customAuthFn: async (app, config, logger) => {
    // Return a middleware function
    return (req, res, next) => {
      // Custom authentication logic
      next();
    };
  }
}

// OAuth2 Authentication
auth: {
  type: 'oauth2',
  oauth2: {
    issuerUrl: 'https://identity.example.com',
    clientId: process.env.OAUTH_CLIENT_ID,
    audience: 'https://api.example.com'
  }
}
```

### Database Connectivity

The framework provides flexible database connectivity options:

```typescript
// PostgreSQL configuration
database: {
  type: 'postgres',
  connection: {
    host: process.env.DB_HOST || 'localhost',
    port: parseInt(process.env.DB_PORT || '5432'),
    username: process.env.DB_USER,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_NAME,
    ssl: process.env.DB_SSL === 'true',
    poolSize: parseInt(process.env.DB_POOL_SIZE || '10')
  }
}

// MongoDB configuration
database: {
  type: 'mongodb',
  connection: {
    uri: process.env.MONGO_URI || 'mongodb://localhost:27017/myapp',
    options: {
      useNewUrlParser: true,
      useUnifiedTopology: true,
      maxPoolSize: 10
    }
  }
}

// Custom database connection
database: {
  type: 'custom',
  initialize: async (config, logger) => {
    // Custom database initialization logic
    const connection = await customDbConnect();
    logger.info('Custom database connected');
    
    // Return connection object and cleanup function
    return {
      connection,
      cleanup: async () => {
        await connection.close();
        logger.info('Custom database disconnected');
      }
    };
  }
}
```

### Advanced Health Checks

Health checks are now powered by @unidev-hub/health, providing Kubernetes-compatible health endpoints:

```typescript
import { startServer, Status } from '@unidev-hub/api-framework';

// Configure health checks
startServer({
  // ...other options
  health: {
    // Custom health indicators
    customIndicators: [
      {
        name: 'redis-cache',
        check: async () => {
          // Check if Redis is healthy
          return {
            status: Status.UP,
            details: { responseTime: '5ms' }
          };
        }
      }
    ],
    
    // HTTP dependency checks
    httpDependencies: [
      {
        name: 'auth-service',
        url: 'http://auth-service/health',
        timeout: 2000
      }
    ],
    
    // Database health checks (automatically configured if database is set up)
    database: {
      enabled: true,
      timeout: 3000
    },
    
    // Memory usage thresholds
    memory: {
      enabled: true,
      threshold: 90 // Percentage
    },
    
    // CPU usage thresholds
    cpu: {
      enabled: true,
      threshold: 80 // Percentage
    }
  }
});
```

This provides four standard health check endpoints:
- `/health`: Basic health status
- `/health/liveness`: Kubernetes liveness probe
- `/health/readiness`: Kubernetes readiness probe
- `/health/details`: Detailed health report

### Middleware Configuration

Configure custom middleware for your API:

```typescript
startServer({
  // ...other options
  middleware: {
    // Global middleware to execute before routes
    before: [
      (req, res, next) => {
        // Add request timestamp
        req.timestamp = new Date();
        next();
      },
      // Add third-party middleware
      compression(),
      cookieParser()
    ],
    
    // Route-specific middleware (applied only to routes under a specific path)
    routes: [
      {
        path: '/uploads',
        handlers: [
          multer({ dest: 'uploads/' }).single('file'),
          (req, res, next) => {
            // Process uploaded files
            next();
          }
        ]
      }
    ],
    
    // Global middleware to execute
