UNPKG

@iota-big3/sdk-gateway

Version:

Universal API Gateway with protocol translation, intelligent routing, rate limiting, health checking, and caching

947 lines (739 loc) 22 kB
# SDK Gateway API Reference ## Table of Contents - [Gateway Configuration](#gateway-configuration) - [Gateway Methods](#gateway-methods) - [Service Management](#service-management) - [Route Management](#route-management) - [Rate Limiting](#rate-limiting) - [Health Checking](#health-checking) - [Caching](#caching) - [Metrics & Monitoring](#metrics--monitoring) - [Chaos Engineering](#chaos-engineering) 🆕 - [Performance Monitoring](#performance-monitoring) 🆕 - [Production Smoke Tests](#production-smoke-tests) 🆕 - [Events](#events) - [Type Definitions](#type-definitions) ## Gateway Configuration ### `createGateway(config: GatewayConfig): UniversalAPIGateway` Creates a new gateway instance. ```typescript const gateway = createGateway({ // Basic Configuration name: "My API Gateway", // Gateway name for identification port: 8080, // Port to listen on host: "0.0.0.0", // Host to bind to // Feature Toggles enableMetrics: true, // Enable metrics collection enableSLA: true, // Enable SLA monitoring enableCostTracking: true, // Enable cost tracking // Service Discovery discoveryType: "static", // 'static' | 'kubernetes' | 'consul' | 'etcd' // Rate Limiting rateLimit: { windowMs: 60000, // Time window in milliseconds max: 100, // Max requests per window keyGenerator: (req) => req.context?.userId || "anonymous", skip: (req) => req.path === "/health", onLimitReached: (info) => console.log("Rate limit exceeded"), }, // Health Checking healthCheck: { enabled: true, interval: 30000, // Check interval in ms timeout: 5000, // Request timeout in ms retries: 3, // Number of retries retryDelay: 1000, // Delay between retries }, // Caching caching: { enabled: true, ttl: 300, // Default TTL in seconds maxSize: 1000, // Max cache entries strategy: "lru", // 'lru' | 'lfu' | 'fifo' excludePaths: ["/admin/*"], keyGenerator: (req) => `${req.method}:${req.path}`, store: customCacheStore, // Optional custom store }, // Cost Tracking cost: { enabled: true, model: "per-request", // Billing model rate: 0.0001, // Cost per unit currency: "USD", limits: { daily: 10, monthly: 250, }, }, }); ``` ## Gateway Methods ### Core Methods #### `gateway.start(): Promise<void>` Starts the gateway server. ```typescript await gateway.start(); console.log("Gateway is running"); ``` #### `gateway.stop(): Promise<void>` Stops the gateway server gracefully. ```typescript await gateway.stop(); ``` #### `gateway.enable(): void` Enables the gateway (accepts requests). ```typescript gateway.enable(); ``` #### `gateway.disable(): void` Disables the gateway (returns 503 for all requests). ```typescript gateway.disable(); ``` #### `gateway.isGatewayEnabled(): boolean` Checks if the gateway is enabled. ```typescript if (gateway.isGatewayEnabled()) { console.log("Gateway is accepting requests"); } ``` #### `gateway.isGatewayRunning(): boolean` Checks if the gateway server is running. ```typescript if (gateway.isGatewayRunning()) { console.log("Server is active"); } ``` #### `gateway.updateConfig(config: Partial<GatewayConfig>): void` Updates gateway configuration at runtime. ```typescript gateway.updateConfig({ rateLimit: { max: 200 }, caching: { ttl: 600 }, }); ``` ## Service Management ### `gateway.registerService(service: ServiceEndpoint): Promise<void>` Registers a backend service. ```typescript await gateway.registerService({ id: "user-service-1", // Unique service ID name: "user-service", // Service name host: "localhost", // Service host port: 3001, // Service port protocol: "http", // Protocol version: "1.0.0", // Optional version weight: 1, // Optional weight for load balancing healthCheck: "/health", // Health check endpoint metadata: { // Optional metadata region: "us-east-1", environment: "production", }, }); ``` ### `gateway.unregisterService(serviceId: string): Promise<void>` Removes a service from the registry. ```typescript await gateway.unregisterService("user-service-1"); ``` ### `gateway.getServices(): ServiceEndpoint[]` Gets all registered services. ```typescript const services = gateway.getServices(); ``` ## Route Management ### `gateway.registerRoute(route: RouteConfig): void` Registers a new route. ```typescript gateway.registerRoute({ id: "users-route", // Unique route ID path: "/api/users/*", // Route path pattern service: "user-service", // Target service name methods: ["GET", "POST"], // Allowed methods (optional) // Load balancing loadBalance: { strategy: "round-robin", // 'round-robin' | 'random' | 'weighted' | 'least-connections' }, // Circuit breaker circuitBreaker: { failureThreshold: 5, recoveryTimeout: 30000, monitoringPeriod: 60000, }, // Rate limiting (route-specific) rateLimit: { windowMs: 10000, max: 50, }, // Request/Response transformation transform: { request: { headers: { "X-Custom": "value" }, removeHeaders: ["X-Internal"], }, response: { headers: { "X-Response-Time": "${latency}ms" }, }, }, }); ``` ### `gateway.removeRoute(routeId: string): boolean` Removes a route. ```typescript const removed = gateway.removeRoute("users-route"); // returns true if removed ``` ### `gateway.getRoutes(): RouteConfig[]` Gets all configured routes. ```typescript const routes = gateway.getRoutes(); ``` ## Rate Limiting ### `gateway.getRateLimiter(): RateLimiter | undefined` Gets the rate limiter instance. ```typescript const rateLimiter = gateway.getRateLimiter(); if (rateLimiter) { // Check rate limit for a request const result = await rateLimiter.checkLimit(request); console.log("Allowed:", result.allowed); console.log("Remaining:", result.remaining); // Get metrics const metrics = rateLimiter.getMetrics(); console.log("Blocked requests:", metrics.blockedRequests); // Reset limits for a key await rateLimiter.reset("user-123"); } ``` ## Health Checking ### `gateway.getHealthChecker(): HealthChecker | undefined` Gets the health checker instance. ```typescript const healthChecker = gateway.getHealthChecker(); if (healthChecker) { // Add custom health check healthChecker.addCheck("database", async () => { const healthy = await checkDatabaseConnection(); return { status: healthy ? "healthy" : "unhealthy", details: { connectionPool: getPoolSize() }, }; }); // Check specific service const result = await healthChecker.checkHealth("database"); console.log("Database status:", result.status); // Get overall health const overall = await healthChecker.getOverallHealth(); console.log("System health:", overall.status); } ``` ### `gateway.getHealthStatus(): Promise<OverallHealth | { status: string; message: string }>` Gets the complete health status of the gateway. ```typescript const health = await gateway.getHealthStatus(); console.log(health); // { // status: 'healthy', // services: { // 'user-service': { status: 'healthy', lastCheck: '...' }, // 'order-service': { status: 'unhealthy', error: '...' } // }, // checks: { // 'database': { status: 'healthy', details: {...} } // }, // timestamp: 1234567890 // } ``` ## Caching ### `gateway.getCacheManager(): CacheManager | undefined` Gets the cache manager instance. ```typescript const cacheManager = gateway.getCacheManager(); if (cacheManager) { // Manually cache a response await cacheManager.set("custom-key", { data: "value" }, 300); // Get cached value const cached = await cacheManager.get("custom-key"); // Invalidate cache await cacheManager.invalidatePattern("/api/users/*"); await cacheManager.invalidateTag("users"); // Get cache statistics const stats = cacheManager.getStats(); console.log("Cache hit rate:", stats.hitRate); } ``` ## Metrics & Monitoring ### `gateway.getMetrics(): GatewayMetrics & { cache?: CacheStats }` Gets comprehensive gateway metrics. ```typescript const metrics = await gateway.getMetrics(); console.log(metrics); // { // requests: { // total: 1000000, // rate: 250, // active: 45 // }, // latency: { // avg: 45, // p50: 35, // p95: 120, // p99: 200 // }, // errors: { // total: 1500, // rate: 0.15, // types: { // '4xx': 1000, // '5xx': 500 // } // }, // circuitBreakers: { // open: 0, // halfOpen: 1, // closed: 4 // }, // services: { // healthy: 5, // unhealthy: 0 // }, // cache: { // hits: 45000, // misses: 15000, // hitRate: 0.75, // size: 750, // evictions: 250 // } // } ``` ### SLA Monitoring #### `gateway.addSLA(routePath: string, config: SLAConfig): void` Adds SLA requirements for a route. ```typescript gateway.addSLA("/api/critical/*", { responseTime: 200, // Max response time in ms errorRate: 0.01, // Max error rate (1%) availability: 99.9, // Min availability (99.9%) }); ``` #### `gateway.getSLAStatus(routePath: string): SLAStatus | null` Gets SLA compliance status for a route. ```typescript const status = gateway.getSLAStatus("/api/critical/*"); if (status) { console.log("SLA Compliant:", status.isCompliant); console.log("Avg Response Time:", status.responseTime.average); console.log("Current Error Rate:", status.errorRate.current); } ``` ### Cost Tracking #### `gateway.getCostReport(): Promise<CostReport>` Gets detailed cost report. ```typescript const report = await gateway.getCostReport(); console.log("Daily cost:", report.current.day); console.log("Projected monthly:", report.projected.month); console.log("Top consumers:", report.breakdown.topConsumers); ``` ## Events The gateway emits various events for monitoring and integration: ```typescript // Request lifecycle gateway.on("request:start", (request: GatewayRequest) => { console.log("Request started:", request.id); }); gateway.on( "request:end", (request: GatewayRequest, response: GatewayResponse) => { console.log("Request completed:", response.statusCode); } ); // Circuit breaker events gateway.on("circuit:opened", (info: { service: string; failures: number }) => { console.log("Circuit opened for:", info.service); }); gateway.on("circuit:closed", (info: { service: string }) => { console.log("Circuit closed for:", info.service); }); // Rate limiting gateway.on("rateLimit:exceeded", (info: { key: string; limit: number }) => { console.log("Rate limit exceeded for:", info.key); }); // SLA violations gateway.on("sla:violation", (violation: SLAViolation) => { console.log("SLA violated:", violation.type, violation.route); }); // Health status changes gateway.on( "health:statusChanged", (info: { service: string; status: string }) => { console.log("Health status changed:", info.service, info.status); } ); // Cache events gateway.on("cache:hit", (info: { key: string }) => { console.log("Cache hit:", info.key); }); gateway.on("cache:miss", (info: { key: string }) => { console.log("Cache miss:", info.key); }); ``` ## Chaos Engineering ### `new ChaosMiddleware(options: ChaosOptions)` Creates a chaos engineering middleware for controlled failure injection. ```typescript import { ChaosMiddleware } from "@iota-big3/sdk-gateway"; const chaos = new ChaosMiddleware({ enabled: true, failures: { networkLatency: { probability: 0.1, // 10% of requests minMs: 100, // Minimum delay maxMs: 500, // Maximum delay }, serviceFailure: { probability: 0.05, // 5% of requests statusCodes: [500, 503, 429], }, timeouts: { probability: 0.02, // 2% of requests duration: 5000, // 5 second timeout }, resourceExhaustion: { probability: 0.01, // 1% of requests type: "cpu", // 'cpu' | 'memory' | 'connections' }, malformedResponse: { probability: 0.03, // 3% of requests types: ["truncated", "invalid-json", "empty", "huge"], }, }, seed: 42, // Optional: for deterministic chaos }); ``` #### Methods ##### `chaos.injectChaos(request: GatewayRequest): Promise<void>` Injects chaos into a request based on configured probabilities. ```typescript try { await chaos.injectChaos(request); } catch (error) { if (error instanceof ChaosError) { console.log("Chaos injected:", error.type); } } ``` ##### `chaos.transformResponse(response: GatewayResponse): GatewayResponse` Transforms responses to simulate malformed data. ```typescript const malformedResponse = chaos.transformResponse(response); ``` ##### `chaos.getStatistics(): ChaosStatistics` Gets chaos injection statistics. ```typescript const stats = chaos.getStatistics(); console.log("Injections:", stats.injections); // { networkLatency: 45, serviceFailure: 23, ... } ``` ##### `chaos.enable() / chaos.disable()` Enable or disable chaos injection at runtime. ```typescript // Disable for production chaos.disable(); // Enable for testing chaos.enable(); ``` ##### `chaos.reset()` Reset all statistics. ```typescript chaos.reset(); ``` #### Events ```typescript // Chaos injection events chaos.on("chaos:injected", (event) => { console.log(`Injected ${event.type} for request ${event.request}`); // Log to monitoring service }); chaos.on("chaos:enabled", () => { console.log("Chaos engineering enabled"); }); chaos.on("chaos:disabled", () => { console.log("Chaos engineering disabled"); }); ``` ## Performance Monitoring ### `new PerformanceMonitor(thresholds?: PerformanceThresholds)` Creates a performance monitoring instance with anomaly detection. ```typescript import { PerformanceMonitor } from "@iota-big3/sdk-gateway"; const monitor = new PerformanceMonitor({ latency: { p50: 50, // 50ms median threshold p95: 150, // 150ms 95th percentile threshold p99: 300, // 300ms 99th percentile threshold }, errorRate: 0.01, // 1% error rate threshold throughput: { min: 100, // Minimum 100 req/sec max: 10000, // Maximum 10k req/sec }, memory: { max: 512, // 512MB max memory growthRate: 10, // 10MB/hour growth allowed }, }); ``` #### Methods ##### `monitor.startRequest(request: GatewayRequest): void` Start tracking a request. ```typescript monitor.startRequest(request); ``` ##### `monitor.endRequest(request: GatewayRequest, response: GatewayResponse): void` End tracking a request and record metrics. ```typescript monitor.endRequest(request, response); ``` ##### `monitor.getMetrics(): PerformanceMetrics` Get comprehensive performance metrics. ```typescript const metrics = monitor.getMetrics(); console.log({ requestRate: metrics.requests.rate, // req/sec activeRequests: metrics.requests.active, p50Latency: metrics.latency.p50, // ms p95Latency: metrics.latency.p95, // ms p99Latency: metrics.latency.p99, // ms errorRate: metrics.errors.rate, // percentage throughput: metrics.throughput.current, // bytes/sec cpuUsage: metrics.resources.cpu.usage, // percentage memoryUsed: metrics.resources.memory.heapUsed, // MB }); ``` ##### `monitor.detectAnomalies(): Anomaly[]` Detect performance anomalies based on thresholds. ```typescript const anomalies = monitor.detectAnomalies(); anomalies.forEach((anomaly) => { console.log(`${anomaly.type} anomaly: ${anomaly.message}`); console.log(`Severity: ${anomaly.severity}`); console.log(`Value: ${anomaly.value}, Threshold: ${anomaly.threshold}`); }); ``` ##### `monitor.getAnomalies(): Anomaly[]` Get current detected anomalies. ```typescript const currentAnomalies = monitor.getAnomalies(); ``` ##### `monitor.reset()` Reset all metrics and anomalies. ```typescript monitor.reset(); ``` #### Events ```typescript // Critical anomaly detection monitor.on("anomaly:critical", (anomaly) => { console.error("Critical anomaly:", anomaly); // Trigger immediate action }); // Request timeout detection monitor.on("request:timeout", ({ id, duration }) => { console.warn(`Request ${id} timed out after ${duration}ms`); }); // Monitor reset monitor.on("monitor:reset", () => { console.log("Performance monitor reset"); }); ``` ## Production Smoke Tests ### `runSmokeTests(gatewayUrl: string, options?: SmokeTestOptions): Promise<SmokeTestResult[]>` Run production smoke tests against a gateway. ```typescript import { runSmokeTests, generateReport } from "@iota-big3/sdk-gateway"; const results = await runSmokeTests("https://api.production.com", { parallel: true, // Run tests in parallel stopOnFailure: true, // Stop on first failure filter: (test) => test.critical, // Only run critical tests }); const report = generateReport(results); ``` #### Options ```typescript interface SmokeTestOptions { stopOnFailure?: boolean; // Stop on first failure parallel?: boolean; // Run tests in parallel filter?: (test: SmokeTest) => boolean; // Filter tests } ``` #### Built-in Smoke Tests 1. **Health Check Endpoint** (critical) - Validates `/health` returns 200 - Checks response time < 100ms - Verifies health status 2. **Service Discovery** (critical) - Validates service registry - Checks for healthy services - Verifies service count > 0 3. **Request Routing** - Tests basic routing functionality - Validates routing headers - Checks latency < 200ms 4. **Rate Limiting** - Verifies rate limiting works - Checks for 429 responses - Validates retry-after header 5. **Circuit Breaker** - Tests circuit breaker functionality - Verifies circuit opens on failures - Checks circuit state header 6. **Cache Functionality** - Tests cache hit/miss - Validates cache headers - Verifies content consistency 7. **Authentication** - Tests auth requirements - Validates 401/403 responses - Checks auth headers 8. **Metrics Endpoint** - Validates `/metrics` endpoint - Checks metric format - Verifies essential metrics ### `generateReport(results: SmokeTestResult[]): SmokeTestReport` Generate a comprehensive report from smoke test results. ```typescript const report = generateReport(results); console.log(`Total Tests: ${report.summary.total}`); console.log(`Passed: ${report.summary.passed}`); console.log(`Failed: ${report.summary.failed}`); console.log(`Pass Rate: ${report.summary.passRate}%`); console.log(`Duration: ${report.summary.duration}ms`); // Failed tests report.failures.forEach((failure) => { console.error(`❌ ${failure.name}: ${failure.error}`); }); // Slow tests (> 1 second) report.slowTests.forEach((test) => { console.warn(`⚠️ ${test.name}: ${test.duration}ms`); }); ``` ### Custom Smoke Tests You can add custom smoke tests: ```typescript const customTests: SmokeTest[] = [ { name: "Custom API Test", critical: true, timeout: 5000, test: async (gateway) => { const response = await fetch(`${gateway}/api/custom`); if (response.status !== 200) { throw new Error(`Expected 200, got ${response.status}`); } }, }, ]; // Add to existing tests const allTests = [...criticalPaths, ...customTests]; ``` ## Type Definitions For complete type definitions, see [`src/types/gateway-types.ts`](./src/types/gateway-types.ts). Key types include: - `GatewayConfig` - Main configuration interface - `ServiceEndpoint` - Service registration details - `RouteConfig` - Route configuration - `GatewayRequest` - Incoming request structure - `GatewayResponse` - Outgoing response structure - `GatewayMetrics` - Metrics data structure - `HealthStatus` - Health check status - `RateLimitResult` - Rate limit check result - `CacheEntry` - Cache entry structure - `SLAConfig` - SLA requirements - `CostReport` - Cost tracking report ### Phase 2k Production Types ```typescript // Chaos Engineering Types interface ChaosOptions { enabled: boolean; failures: { networkLatency: { probability: number; minMs: number; maxMs: number }; serviceFailure: { probability: number; statusCodes: number[] }; timeouts: { probability: number; duration: number }; resourceExhaustion: { probability: number; type: "cpu" | "memory" | "connections"; }; malformedResponse: { probability: number; types: ("truncated" | "invalid-json" | "empty" | "huge")[]; }; }; seed?: number; // For deterministic chaos } // Performance Monitoring Types interface PerformanceThresholds { latency: { p50: number; p95: number; p99: number }; errorRate: number; throughput: { min: number; max: number }; memory: { max: number; growthRate: number }; } interface Anomaly { type: "latency" | "error_rate" | "throughput" | "memory" | "cpu"; severity: "low" | "medium" | "high" | "critical"; value: number; threshold: number; timestamp: number; message: string; } interface PerformanceMetrics { requests: { total: number; rate: number; active: number }; latency: { current: number; p50: number; p95: number; p99: number; avg: number; min: number; max: number; }; errors: { total: number; rate: number; byType: Record<string, number> }; throughput: { current: number; avg: number; peak: number }; resources: { cpu: { usage: number; system: number; user: number }; memory: { used: number; rss: number; heapUsed: number; heapTotal: number; external: number; }; connections: { active: number; idle: number; waiting: number }; }; } // Smoke Test Types interface SmokeTest { name: string; test: (gateway: string) => Promise<void>; timeout?: number; critical?: boolean; } interface SmokeTestResult { name: string; passed: boolean; duration: number; error?: string; details?: Record<string, unknown>; } interface SmokeTestReport { summary: { total: number; passed: number; failed: number; duration: number; passRate: number; }; failures: SmokeTestResult[]; slowTests: SmokeTestResult[]; } ```