⚡ Comprehensive TypeScript type definitions for HSuite Rate Limiting ecosystem with flexible storage backends
Enterprise-grade type definitions and interfaces providing a robust foundation for implementing rate limiting functionality across NestJS applications with support for Redis, in-memory storage, and dynamic configuration patterns.
📚 Table of Contents
✨ Quick Start
Installation
Copy npm install @hsuite/throttler-types
Basic Setup
Copy import { IThrottler, Throttler } from '@hsuite/throttler-types';
// Interface-based type definitions
const options: IThrottler.IOptions = {
enabled: true,
settings: {
ttl: 60, // Time window in seconds
limit: 100 // Maximum requests per window
},
storage: IThrottler.IStorage.REDIS,
redis: {
host: 'localhost',
port: 6379
}
};
NestJS Integration
Copy import { ThrottlerModule } from '@hsuite/throttler';
import { IThrottler } from '@hsuite/throttler-types';
@Module({
imports: [
ThrottlerModule.forRootAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService): Promise<IThrottler.IOptions> => ({
enabled: configService.get<boolean>('THROTTLE_ENABLED', true),
settings: {
ttl: configService.get<number>('THROTTLE_TTL', 60),
limit: configService.get<number>('THROTTLE_LIMIT', 100)
},
storage: IThrottler.IStorage.REDIS,
redis: {
host: configService.get<string>('REDIS_HOST', 'localhost'),
port: configService.get<number>('REDIS_PORT', 6379)
}
}),
inject: [ConfigService]
})
]
})
export class AppModule {}
🏗️ Architecture
Core Component Areas
⚡ Rate Limiting Foundation
Storage Backends - Redis and in-memory storage options for scalability
Configuration Management - Flexible settings for TTL, limits, and storage
Factory Patterns - Dynamic configuration with dependency injection
Type Safety - Comprehensive TypeScript interfaces and validation
🏭 Factory Pattern Integration
Options Factory - Interface for dynamic configuration creation
Async Configuration - Support for runtime configuration loading
Dependency Injection - Clean integration with NestJS DI system
Environment Flexibility - Different configurations for various environments
🔄 Storage Backend Support
Redis Storage - Distributed storage for scalable rate limiting
In-Memory Storage - Local storage for simple deployments
Configuration Options - Complete Redis client configuration support
Fallback Mechanisms - Graceful degradation and error handling
🛡️ Enterprise Features
Multi-Tenant Support - Tenant-specific rate limiting configurations
Tier-Based Limiting - Different limits based on user tiers
Dynamic Adjustment - Runtime configuration changes
Monitoring Integration - Type-safe monitoring and metrics
Module Structure
Copy src/
├── index.ts # Main exports and documentation
├── interfaces/
│ └── throttler.namespace.ts # Core interfaces and enums
└── models/
└── throttler.namespace.ts # Model types and utilities
🔧 API Reference
Core Interface Types
Storage Backend Types
IThrottler.IStorage
Purpose : Available storage options for persisting throttling data
Usage : Storage backend selection for rate limiting data
Configuration Types
IThrottler.IOptions
Purpose : Complete throttler configuration interface
Properties : enabled, settings, storage, redis
Usage : Main configuration object for throttler setup
IThrottler.IOptionsFactory
Purpose : Factory interface for dynamic configuration
Methods : createThrottlerOptions()
Usage : Runtime configuration generation
Module Configuration Types
IThrottler.IModuleAsyncOptions
Purpose : Async module configuration for throttler initialization
Properties : useClass, useFactory, inject
Usage : NestJS module async configuration
Storage Selection Guidelines
Storage Type
Use Case
Scalability
Performance
Complexity
Development, Single Instance
Configuration Parameters
Parameter
Type
Description
Default
Required
📖 Guides
Rate Limiting Setup Guide
Complete guide to setting up rate limiting with different storage backends. Comprehensive setup instructions covering Redis and in-memory storage configuration, TTL and limit settings, environment-specific configurations, and performance optimization for enterprise-scale rate limiting systems.
Factory Pattern Guide
Learn how to implement dynamic configuration with factory patterns. Advanced implementation guide covering factory pattern integration, dynamic configuration loading, environment-based config selection, tenant-specific overrides, and runtime configuration validation for flexible throttling systems.
Multi-Tenant Configuration Guide
Set up tenant-specific and tier-based rate limiting configurations. Detailed guide for implementing multi-tenant rate limiting with tier-based limits, tenant isolation, configuration inheritance, custom Redis key prefixes, and enterprise-grade tenant management.
Production Deployment Guide
Best practices for deploying rate limiting in production environments. Comprehensive deployment guide covering Redis clustering, performance monitoring, error handling, failover strategies, and production optimization for high-availability rate limiting systems.
🎯 Examples
Storage Backend Configuration
Copy import { IThrottler } from '@hsuite/throttler-types';
@Injectable()
export class ThrottlerStorageService {
// Redis storage configuration for production
getRedisConfiguration(): IThrottler.IOptions {
return {
enabled: true,
settings: { ttl: 60, limit: 100 },
storage: IThrottler.IStorage.REDIS,
redis: {
host: process.env.REDIS_HOST || 'localhost',
port: parseInt(process.env.REDIS_PORT || '6379'),
password: process.env.REDIS_PASSWORD,
username: process.env.REDIS_USERNAME,
database: parseInt(process.env.REDIS_DATABASE || '0'),
retryDelayOnFailover: 100,
maxRetriesPerRequest: 3,
connectTimeout: 20000,
commandTimeout: 5000
}
};
}
// In-memory storage for development
getMemoryConfiguration(): IThrottler.IOptions {
return {
enabled: true,
settings: { ttl: 60, limit: 1000 },
storage: IThrottler.IStorage.DEFAULT,
redis: {} // Required but empty for in-memory
};
}
// Environment-based configuration selection
getEnvironmentConfiguration(): IThrottler.IOptions {
const environment = process.env.NODE_ENV || 'development';
const configs = {
development: this.getMemoryConfiguration(),
staging: {
enabled: true,
settings: { ttl: 60, limit: 500 },
storage: IThrottler.IStorage.REDIS,
redis: { host: 'staging-redis', port: 6379 }
},
production: this.getRedisConfiguration()
};
return configs[environment] || configs.development;
}
validateConfiguration(config: IThrottler.IOptions): boolean {
return (
typeof config.enabled === 'boolean' &&
typeof config.settings.ttl === 'number' &&
typeof config.settings.limit === 'number' &&
config.settings.ttl > 0 &&
config.settings.limit > 0 &&
Object.values(IThrottler.IStorage).includes(config.storage)
);
}
}
Factory Pattern Implementation
Copy import { IThrottler } from '@hsuite/throttler-types';
import { Injectable } from '@nestjs/common';
@Injectable()
export class DynamicThrottlerConfigFactory implements IThrottler.IOptionsFactory {
constructor(
private readonly configService: ConfigService,
private readonly tenantService: TenantService
) {}
async createThrottlerOptions(): Promise<IThrottler.IOptions> {
try {
// Load base configuration
const baseConfig = await this.loadBaseConfiguration();
// Apply tenant-specific overrides
const tenantConfig = await this.loadTenantConfiguration();
// Merge configurations
const finalConfig = this.mergeConfigurations(baseConfig, tenantConfig);
// Validate final configuration
this.validateConfiguration(finalConfig);
return finalConfig;
} catch (error) {
throw new Error(`Throttler configuration creation failed: ${error.message}`);
}
}
private async loadBaseConfiguration(): Promise<IThrottler.IOptions> {
const isProduction = process.env.NODE_ENV === 'production';
return {
enabled: this.configService.get<boolean>('THROTTLING_ENABLED', true),
settings: {
ttl: this.configService.get<number>('THROTTLE_TTL', 60),
limit: this.configService.get<number>('THROTTLE_LIMIT', isProduction ? 100 : 1000)
},
storage: isProduction ? IThrottler.IStorage.REDIS : IThrottler.IStorage.DEFAULT,
redis: {
host: this.configService.get<string>('REDIS_HOST', 'localhost'),
port: this.configService.get<number>('REDIS_PORT', 6379),
password: this.configService.get<string>('REDIS_PASSWORD'),
retryDelayOnFailover: 100,
maxRetriesPerRequest: 3
}
};
}
private async loadTenantConfiguration(): Promise<Partial<IThrottler.IOptions>> {
try {
const tenant = await this.tenantService.getCurrentTenant();
if (!tenant) {
return {};
}
const tierLimits = {
basic: { ttl: 60, limit: 100 },
premium: { ttl: 60, limit: 500 },
enterprise: { ttl: 60, limit: 2000 }
};
return {
settings: tierLimits[tenant.tier] || tierLimits.basic,
redis: {
keyPrefix: `throttler:${tenant.id}:`
}
};
} catch (error) {
console.warn('Failed to load tenant configuration, using defaults:', error);
return {};
}
}
private mergeConfigurations(
base: IThrottler.IOptions,
tenant: Partial<IThrottler.IOptions>
): IThrottler.IOptions {
return {
...base,
settings: {
...base.settings,
...tenant.settings
},
redis: {
...base.redis,
...tenant.redis
}
};
}
private validateConfiguration(config: IThrottler.IOptions): void {
if (!config.enabled && typeof config.enabled !== 'boolean') {
throw new Error('Configuration validation failed: enabled must be boolean');
}
if (config.settings.ttl <= 0) {
throw new Error('Configuration validation failed: TTL must be positive');
}
if (config.settings.limit <= 0) {
throw new Error('Configuration validation failed: limit must be positive');
}
if (!Object.values(IThrottler.IStorage).includes(config.storage)) {
throw new Error('Configuration validation failed: invalid storage type');
}
}
}
Multi-Tenant Rate Limiting
Copy import { IThrottler } from '@hsuite/throttler-types';
interface TenantThrottlerConfig extends IThrottler.IOptions {
tenantId: string;
tier: 'basic' | 'premium' | 'enterprise';
customLimits?: {
endpoint?: string;
limit: number;
ttl: number;
}[];
}
@Injectable()
export class MultiTenantThrottlerService {
async createTenantConfiguration(tenantId: string): Promise<IThrottler.IOptions> {
try {
const tenant = await this.getTenantInfo(tenantId);
const tierConfig = this.getTierConfiguration(tenant.tier);
const customLimits = await this.getCustomLimits(tenantId);
const config: IThrottler.IOptions = {
enabled: tenant.throttlingEnabled,
settings: {
ttl: tierConfig.ttl,
limit: tierConfig.limit
},
storage: IThrottler.IStorage.REDIS,
redis: {
host: process.env.REDIS_HOST,
port: parseInt(process.env.REDIS_PORT || '6379'),
keyPrefix: `throttler:${tenantId}:`,
password: process.env.REDIS_PASSWORD
}
};
// Apply custom limits if available
if (customLimits.length > 0) {
config.redis.keyPrefix = `throttler:custom:${tenantId}:`;
}
return config;
} catch (error) {
throw new Error(`Tenant configuration creation failed: ${error.message}`);
}
}
private getTierConfiguration(tier: string): { ttl: number; limit: number } {
const tierConfigs = {
basic: { ttl: 60, limit: 100 },
premium: { ttl: 60, limit: 500 },
enterprise: { ttl: 60, limit: 2000 }
};
return tierConfigs[tier] || tierConfigs.basic;
}
private async getTenantInfo(tenantId: string): Promise<any> {
// Mock implementation - replace with actual tenant service
return {
id: tenantId,
tier: 'premium',
throttlingEnabled: true,
customSettings: {}
};
}
private async getCustomLimits(tenantId: string): Promise<any[]> {
// Mock implementation - replace with actual custom limits service
return [
{
endpoint: '/api/heavy-operation',
limit: 10,
ttl: 300
}
];
}
async updateTenantLimits(tenantId: string, newLimits: { ttl: number; limit: number }): Promise<void> {
try {
// Validate new limits
if (newLimits.ttl <= 0 || newLimits.limit <= 0) {
throw new Error('TTL and limit must be positive values');
}
// Update tenant configuration
await this.updateTenantConfig(tenantId, newLimits);
// Notify rate limiter of configuration change
await this.notifyConfigurationChange(tenantId);
console.log(`Updated throttling limits for tenant ${tenantId}:`, newLimits);
} catch (error) {
throw new Error(`Failed to update tenant limits: ${error.message}`);
}
}
private async updateTenantConfig(tenantId: string, limits: { ttl: number; limit: number }): Promise<void> {
// Implementation for updating tenant configuration
}
private async notifyConfigurationChange(tenantId: string): Promise<void> {
// Implementation for notifying rate limiter of configuration changes
}
}
Advanced Factory Patterns
Copy import { IThrottler } from '@hsuite/throttler-types';
@Injectable()
export class AdvancedConfigurationService {
// Conditional factory based on feature flags
createConditionalFactory(): IThrottler.IOptionsFactory {
return {
createThrottlerOptions: async (): Promise<IThrottler.IOptions> => {
const featureFlags = await this.getFeatureFlags();
if (featureFlags.advancedThrottling) {
return this.getAdvancedConfiguration();
}
return this.getBasicConfiguration();
}
};
}
// Configuration with circuit breaker pattern
createCircuitBreakerFactory(): IThrottler.IOptionsFactory {
return {
createThrottlerOptions: async (): Promise<IThrottler.IOptions> => {
const healthStatus = await this.checkSystemHealth();
const baseConfig = this.getBasicConfiguration();
if (healthStatus.isUnderHighLoad) {
// Reduce limits during high load
baseConfig.settings.limit = Math.floor(baseConfig.settings.limit * 0.5);
baseConfig.settings.ttl = baseConfig.settings.ttl * 2;
}
return baseConfig;
}
};
}
// Time-based configuration adjustments
createTimeBasedFactory(): IThrottler.IOptionsFactory {
return {
createThrottlerOptions: (): IThrottler.IOptions => {
const currentHour = new Date().getHours();
const isBusinessHours = currentHour >= 9 && currentHour <= 17;
return {
enabled: true,
settings: {
ttl: 60,
limit: isBusinessHours ? 50 : 200 // Stricter limits during business hours
},
storage: IThrottler.IStorage.REDIS,
redis: {
host: process.env.REDIS_HOST || 'localhost',
port: parseInt(process.env.REDIS_PORT || '6379'),
keyPrefix: `throttler:${isBusinessHours ? 'business' : 'off'}:`
}
};
}
};
}
// Gradual rollout configuration factory
createGradualRolloutFactory(rolloutPercentage: number): IThrottler.IOptionsFactory {
return {
createThrottlerOptions: async (): Promise<IThrottler.IOptions> => {
const baseConfig = this.getBasicConfiguration();
// Determine if this instance should use new configuration
const shouldUseNewConfig = Math.random() * 100 < rolloutPercentage;
if (shouldUseNewConfig) {
const newConfig = await this.getExperimentalConfiguration();
return newConfig;
}
return baseConfig;
}
};
}
private getBasicConfiguration(): IThrottler.IOptions {
return {
enabled: true,
settings: { ttl: 60, limit: 100 },
storage: IThrottler.IStorage.REDIS,
redis: {
host: process.env.REDIS_HOST || 'localhost',
port: parseInt(process.env.REDIS_PORT || '6379')
}
};
}
private getAdvancedConfiguration(): IThrottler.IOptions {
return {
enabled: true,
settings: { ttl: 60, limit: 200 },
storage: IThrottler.IStorage.REDIS,
redis: {
host: process.env.REDIS_HOST || 'localhost',
port: parseInt(process.env.REDIS_PORT || '6379'),
retryDelayOnFailover: 100,
maxRetriesPerRequest: 3,
connectTimeout: 20000
}
};
}
private async getExperimentalConfiguration(): Promise<IThrottler.IOptions> {
return {
enabled: true,
settings: { ttl: 30, limit: 150 }, // Experimental settings
storage: IThrottler.IStorage.REDIS,
redis: {
host: process.env.REDIS_HOST || 'localhost',
port: parseInt(process.env.REDIS_PORT || '6379'),
keyPrefix: 'throttler:experimental:'
}
};
}
private async getFeatureFlags(): Promise<{ advancedThrottling: boolean }> {
// Mock implementation
return { advancedThrottling: true };
}
private async checkSystemHealth(): Promise<{ isUnderHighLoad: boolean }> {
// Mock implementation
return { isUnderHighLoad: false };
}
}
Type-Safe Configuration Validation
Copy import { IThrottler } from '@hsuite/throttler-types';
@Injectable()
export class ConfigurationValidationService {
validateConfiguration(config: IThrottler.IOptions): { isValid: boolean; errors: string[] } {
const errors: string[] = [];
// Validate enabled flag
if (typeof config.enabled !== 'boolean') {
errors.push('enabled must be a boolean value');
}
// Validate settings
if (!config.settings) {
errors.push('settings object is required');
} else {
if (typeof config.settings.ttl !== 'number' || config.settings.ttl <= 0) {
errors.push('settings.ttl must be a positive number');
}
if (typeof config.settings.limit !== 'number' || config.settings.limit <= 0) {
errors.push('settings.limit must be a positive number');
}
}
// Validate storage type
if (!Object.values(IThrottler.IStorage).includes(config.storage)) {
errors.push(`storage must be one of: ${Object.values(IThrottler.IStorage).join(', ')}`);
}
// Validate Redis configuration
if (config.storage === IThrottler.IStorage.REDIS) {
if (!config.redis) {
errors.push('redis configuration is required when using Redis storage');
} else {
if (!config.redis.host) {
errors.push('redis.host is required');
}
if (typeof config.redis.port !== 'number' || config.redis.port <= 0) {
errors.push('redis.port must be a positive number');
}
}
}
return {
isValid: errors.length === 0,
errors
};
}
createValidatedFactory(baseFactory: IThrottler.IOptionsFactory): IThrottler.IOptionsFactory {
return {
createThrottlerOptions: async (): Promise<IThrottler.IOptions> => {
const config = await baseFactory.createThrottlerOptions();
const validation = this.validateConfiguration(config);
if (!validation.isValid) {
throw new Error(`Configuration validation failed: ${validation.errors.join(', ')}`);
}
return config;
}
};
}
sanitizeConfiguration(config: Partial<IThrottler.IOptions>): IThrottler.IOptions {
return {
enabled: config.enabled ?? true,
settings: {
ttl: Math.max(1, config.settings?.ttl ?? 60),
limit: Math.max(1, config.settings?.limit ?? 100)
},
storage: config.storage ?? IThrottler.IStorage.DEFAULT,
redis: {
host: config.redis?.host ?? 'localhost',
port: config.redis?.port ?? 6379,
...config.redis
}
};
}
}
🔗 Integration
Required Dependencies
Copy {
"@nestjs/common": "^10.4.2",
"@nestjs/core": "^10.4.2",
"@compodoc/compodoc": "^1.1.23"
}
Module Integration
Copy import { Module } from '@nestjs/common';
import { IThrottler } from '@hsuite/throttler-types';
@Module({
providers: [
ThrottlerStorageService,
DynamicThrottlerConfigFactory,
MultiTenantThrottlerService,
ConfigurationValidationService
],
exports: [
ThrottlerStorageService,
DynamicThrottlerConfigFactory,
MultiTenantThrottlerService,
ConfigurationValidationService
]
})
export class ThrottlerTypesModule {}
Documentation Generation
Copy # Generate comprehensive documentation
npm run compodoc
# Generate documentation with coverage report
npm run compodoc:coverage
Integration with HSuite Ecosystem
Copy // Complete integration with other HSuite modules
import { IThrottler } from '@hsuite/throttler-types';
import { AuthModule } from '@hsuite/auth';
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [
ConfigModule,
AuthModule,
ThrottlerModule.forRootAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService): Promise<IThrottler.IOptions> => {
return {
enabled: configService.get<boolean>('THROTTLE_ENABLED', true),
settings: {
ttl: configService.get<number>('THROTTLE_TTL', 60),
limit: configService.get<number>('THROTTLE_LIMIT', 100)
},
storage: configService.get<string>('NODE_ENV') === 'production'
? IThrottler.IStorage.REDIS
: IThrottler.IStorage.DEFAULT,
redis: {
host: configService.get<string>('REDIS_HOST', 'localhost'),
port: configService.get<number>('REDIS_PORT', 6379),
password: configService.get<string>('REDIS_PASSWORD'),
retryDelayOnFailover: 100,
maxRetriesPerRequest: 3
}
};
},
inject: [ConfigService]
})
]
})
export class ThrottlerEcosystemModule {}
@Injectable()
export class IntegratedThrottlerService {
constructor(
private configService: ConfigService,
private authService: AuthService
) {}
async createUserSpecificLimits(userId: string): Promise<IThrottler.IOptions> {
// Get user tier from auth service
const userTier = await this.authService.getUserTier(userId);
const tierLimits = {
basic: { ttl: 60, limit: 50 },
premium: { ttl: 60, limit: 200 },
enterprise: { ttl: 60, limit: 1000 }
};
return {
enabled: true,
settings: tierLimits[userTier] || tierLimits.basic,
storage: IThrottler.IStorage.REDIS,
redis: {
host: this.configService.get<string>('REDIS_HOST'),
port: this.configService.get<number>('REDIS_PORT'),
keyPrefix: `throttler:user:${userId}:`
}
};
}
}
Use Cases
🌐 API Rate Limiting
RESTful API endpoint protection
GraphQL query rate limiting
WebSocket connection throttling
🛡️ DDoS Protection
Request flooding prevention
🔧 Resource Usage Control
Database connection throttling
CPU-intensive operation limiting
Third-party API call limiting
🏢 Multi-Tenant Applications
Tenant-specific rate limits
Fair resource distribution
⚡ Enterprise Rate Limiting : Comprehensive TypeScript definitions with flexible storage backends and dynamic configuration support.
🏭 Factory Pattern Integration : Clean dependency injection with async configuration capabilities for complex deployment scenarios.
🔄 Multi-Storage Support : Redis for distributed systems and in-memory for simple deployments with seamless switching.
Built with ❤️ by the HbarSuite Team
Copyright © 2024 HbarSuite. All rights reserved.