Skip to content

Commit 175019c

Browse files
feat: implement Redis for distributed rate limiting and caching (#171, #85)
1 parent 36125e1 commit 175019c

5 files changed

Lines changed: 238 additions & 7 deletions

File tree

.env.example

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# Database Configuration
22
DATABASE_URL="postgresql://postgres:password@localhost:5432/tradeflow?schema=public"
33

4-
# Alternative Database Configuration (for TypeORM)
5-
DB_HOST=localhost
6-
DB_PORT=5432
7-
DB_USERNAME=postgres
8-
DB_PASSWORD=password
9-
DB_DATABASE=tradeflow
4+
# Redis Configuration
5+
REDIS_URL="redis://localhost:6379"
6+
7+
# Security Configuration
8+
JWT_SECRET="generate-a-safe-secret-key-here"
9+
ADMIN_PASSWORD="TradeFlow2026!"

config/redis.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* Centralized Redis Client Connection
3+
* Shared across API instances for rate limiting and price caching
4+
*/
5+
const Redis = require('ioredis');
6+
7+
// In a real production deployment, this URL would come from environment
8+
const REDIS_URL = process.env.REDIS_URL || 'redis://localhost:6379';
9+
10+
const redisClient = new Redis(REDIS_URL, {
11+
maxRetriesPerRequest: null,
12+
enableReadyCheck: true
13+
});
14+
15+
redisClient.on('connect', () => {
16+
console.log('🚀 Redis Connection Established - Synchronization Active');
17+
});
18+
19+
redisClient.on('error', (err) => {
20+
console.error('⚠️ Redis Connection Failed:', err.message);
21+
});
22+
23+
module.exports = redisClient;

package-lock.json

Lines changed: 187 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"start:ws": "node server.js"
3232
},
3333
"dependencies": {
34+
"@nest-lab/throttler-storage-redis": "^1.2.0",
3435
"@nestjs/common": "^10.4.22",
3536
"@nestjs/config": "^3.2.3",
3637
"@nestjs/core": "^10.4.22",
@@ -43,9 +44,11 @@
4344
"@types/jsonwebtoken": "^9.0.10",
4445
"axios": "^1.13.6",
4546
"class-validator": "^0.14.4",
47+
"ioredis": "^5.10.1",
4648
"jsonwebtoken": "^9.0.3",
4749
"pg": "^8.11.0",
4850
"prisma": "^5.19.1",
51+
"rate-limit-redis": "^4.3.1",
4952
"reflect-metadata": "^0.2.2",
5053
"rxjs": "^7.8.2",
5154
"swagger-ui-express": "^5.0.0",

src/app.module.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { Module, NestModule, MiddlewareConsumer, RequestMethod } from '@nestjs/common';
22
import { APP_GUARD, APP_FILTER } from '@nestjs/core';
33
import { ThrottlerModule, ThrottlerGuard } from '@nestjs/throttler';
4+
import { ThrottlerStorageRedisService } from '@nest-lab/throttler-storage-redis';
5+
import Redis from 'ioredis';
46
import { AppController } from './app.controller';
57
import { AppService } from './app.service';
68
import { HealthModule } from './health/health.module';
@@ -17,7 +19,23 @@ import { JwtMiddleware } from './common/middleware/jwt.middleware';
1719
import { WebhookController } from './webhooks/webhook.controller';
1820

1921
@Module({
20-
imports: [PrismaModule, HealthModule, RiskModule, AuthModule, AnalyticsModule, SwapModule, TokensModule, OgModule],
22+
imports: [
23+
PrismaModule,
24+
HealthModule,
25+
RiskModule,
26+
AuthModule,
27+
AnalyticsModule,
28+
SwapModule,
29+
TokensModule,
30+
OgModule,
31+
ThrottlerModule.forRoot({
32+
throttlers: [{
33+
ttl: 60000,
34+
limit: 10,
35+
}],
36+
storage: new ThrottlerStorageRedisService(new Redis(process.env.REDIS_URL || 'redis://localhost:6379'))
37+
}),
38+
],
2139
controllers: [AppController, WebhookController],
2240
providers: [
2341
AppService,

0 commit comments

Comments
 (0)