UNPKG

@unidev-hub/api-framework

Version:

A comprehensive framework for building API services with Express

327 lines (276 loc) 7.76 kB
# @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