RateX is a powerful API Gateway that provides rate limiting, request queuing, and proxy capabilities for your APIs. It supports multiple rate limiting strategies and allows you to manage multiple applications through a single gateway.
These rate limiting servers would scale up and down depending upon load and these would communicate with a centralised Redis data store for scalabilty.
At the moment the Users and Apps data strcutures are stored in Redis but in a real scenario they should alwayss be stored in an on-disk database for durability and to avoid data loss.
- Key:
user:<email>(Redis Hash) - Fields:
id: string (UUID)email: stringpassword: string (hashed)organisationName: stringapiKey: string (hashed)createdAt: string (timestamp)
- Associated Set:
user:<email>:apps- Stores App IDs (
app:<uuid>) associated with the user.
- Stores App IDs (
- Key:
app:<uuid>(Redis Hash) - Fields:
id: string (e.g.,app:<uuid>)name: stringbaseUrl: string (URL)userId: string (User's email)rateLimit: string (JSON representation of rate limit config:strategy,window,requests, potentiallyburst,refillRate,leakRate)totalRequests(Optional, inferred from stats endpoint): number
- Key:
queue:<appId>(Redis Sorted Set) - Score: Timestamp of enqueueing
- Member: JSON string representing a Queued Request object.
- Queued Request Object Fields:
id: string (e.g.,req:<timestamp>:<random_string>)appId: string (ID of the target app, e.g.,app:<uuid>)path: string (Requested path)method: string (HTTP method)headers: object (Request headers)body: any (Request body, if applicable)timestamp: number (Enqueue timestamp)
-
Clone the repository
-
Install dependencies:
npm install
-
Create a
.envfile with the following variables:PORT=3000 REDIS_HOST=localhost REDIS_PORT=6379 REDIS_PASSWORD=your_redis_password REDIS_DB=0 JWT_SECRET=your_jwt_secret -
Start Redis server
docker run --name ratex-redis -p 6379:6379 -d redis -
Start the application:
npm start
Redis transactions (MULTI / EXEC) are used to implement ACID to some extent with optimistic concurrency control using WATCH. A simple queueing mechanism is used to queue requests that are rate limited to execute later. The implementation uses hash slots ({strategy:key}) to ensure atomic, isolated, and consistent operations even in a Redis cluster environment, preventing key migration issues and maintaining data consistency across nodes.
-
Fixed Window
- Simple window-based rate limiting
- Resets at fixed intervals
- Configuration:
{ "strategy": "fixed_window", "window": 60, // seconds "requests": 100 // requests per window }
-
Sliding Window
- More accurate rate limiting that considers overlapping windows
- Configuration:
{ "strategy": "sliding_window", "window": 60, "requests": 100 }
-
Token Bucket
- Allows for burst traffic while maintaining average rate
- Configuration:
{ "strategy": "token_bucket", "window": 60, "requests": 100, "burst": 50, "refillRate": 2 }
-
Leaky Bucket
- Smooths out traffic spikes
- Configuration:
{ "strategy": "leaky_bucket", "window": 60, "requests": 100, "leakRate": 2 }
-
Sliding Log
- Most accurate but memory-intensive
- Configuration:
{ "strategy": "sliding_log", "window": 60, "requests": 100 }
- Logs in a user and sets a JWT cookie
- Request body:
{ "email": "user@example.com", "password": "password123" }
- Refreshes the JWT token
- Requires valid JWT cookie
- Logs out the user and clears the JWT cookie
- Requires valid JWT cookie
- Creates a new user
- Request body:
{ "email": "user@example.com", "password": "password123", "organisationName": "My Org" }
- Returns user information
- Requires valid JWT and API key
- Updates user information
- Requires valid JWT and API key
- Request body:
{ "organisationName": "Updated Org Name" }
- Creates a new application to proxy
- Requires valid JWT and API key
- Request body:
{ "name": "My API", "baseUrl": "https://api.example.com", "rateLimit": { "strategy": "fixed_window", "window": 60, "requests": 100 } }
- Lists all applications for the user
- Requires valid JWT and API key
- Gets application details
- Requires valid JWT and API key
- Updates application settings
- Requires valid JWT and API key
- Request body:
{ "name": "Updated API Name", "baseUrl": "https://new-api.example.com", "rateLimit": { "strategy": "sliding_window", "window": 60, "requests": 200 } }
- Deletes an application
- Requires valid JWT and API key
- Gets request statistics for an application
- Requires valid JWT and API key
- Proxies requests to the target API
- Requires valid API key
- Rate limited based on application settings
- Checks the status of a queued request
- Requires valid API key
curl -X POST http://localhost:3000/users \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "password123",
"organisationName": "My Org"
}'curl -X POST http://localhost:3000/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "password123"
}'curl -X POST http://localhost:3000/apps \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"name": "My API",
"baseUrl": "https://api.example.com",
"rateLimit": {
"strategy": "fixed_window",
"window": 60,
"requests": 100
}
}'curl -X GET http://localhost:3000/apis/YOUR_APP_ID/endpoint \curl -X GET http://localhost:3000/apis/status/YOUR_REQUEST_ID \