@unidev-hub/api-framework
Version:
A comprehensive framework for building API services with Express
327 lines (276 loc) • 7.76 kB
Markdown
# @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