Skip to content

Largonarco/RateX

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RateX API Gateway

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.

HLD

HLD

These rate limiting servers would scale up and down depending upon load and these would communicate with a centralised Redis data store for scalabilty.

Database Schema

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.

Users

  • Key: user:<email> (Redis Hash)
  • Fields:
    • id: string (UUID)
    • email: string
    • password: string (hashed)
    • organisationName: string
    • apiKey: string (hashed)
    • createdAt: string (timestamp)
  • Associated Set: user:<email>:apps
    • Stores App IDs (app:<uuid>) associated with the user.

Apps

  • Key: app:<uuid> (Redis Hash)
  • Fields:
    • id: string (e.g., app:<uuid>)
    • name: string
    • baseUrl: string (URL)
    • userId: string (User's email)
    • rateLimit: string (JSON representation of rate limit config: strategy, window, requests, potentially burst, refillRate, leakRate)
    • totalRequests (Optional, inferred from stats endpoint): number

QueueService (Queued Requests)

  • 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)

Setup Instructions

  1. Clone the repository

  2. Install dependencies:

    npm install
  3. Create a .env file 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
    
  4. Start Redis server

    docker run --name ratex-redis -p 6379:6379 -d redis
    
  5. Start the application:

    npm start

Rate Limiting Strategies

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.

  1. Fixed Window

    • Simple window-based rate limiting
    • Resets at fixed intervals
    • Configuration:
      {
      	"strategy": "fixed_window",
      	"window": 60, // seconds
      	"requests": 100 // requests per window
      }
  2. Sliding Window

    • More accurate rate limiting that considers overlapping windows
    • Configuration:
      {
      	"strategy": "sliding_window",
      	"window": 60,
      	"requests": 100
      }
  3. Token Bucket

    • Allows for burst traffic while maintaining average rate
    • Configuration:
      {
      	"strategy": "token_bucket",
      	"window": 60,
      	"requests": 100,
      	"burst": 50,
      	"refillRate": 2
      }
  4. Leaky Bucket

    • Smooths out traffic spikes
    • Configuration:
      {
      	"strategy": "leaky_bucket",
      	"window": 60,
      	"requests": 100,
      	"leakRate": 2
      }
  5. Sliding Log

    • Most accurate but memory-intensive
    • Configuration:
      {
      	"strategy": "sliding_log",
      	"window": 60,
      	"requests": 100
      }

API Endpoints

Authentication (Single layer authentication using JWT)

POST /auth/login

  • Logs in a user and sets a JWT cookie
  • Request body:
    {
    	"email": "user@example.com",
    	"password": "password123"
    }

GET /auth/refresh

  • Refreshes the JWT token
  • Requires valid JWT cookie

GET /auth/logout

  • Logs out the user and clears the JWT cookie
  • Requires valid JWT cookie

Users (Single layer authentication using JWT)

POST /users

  • Creates a new user
  • Request body:
    {
    	"email": "user@example.com",
    	"password": "password123",
    	"organisationName": "My Org"
    }

GET /users

  • Returns user information
  • Requires valid JWT and API key

PUT /users

  • Updates user information
  • Requires valid JWT and API key
  • Request body:
    {
    	"organisationName": "Updated Org Name"
    }

Applications (Dual layer authentication using JWT and API KEY)

POST /apps

  • 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
    	}
    }

GET /apps

  • Lists all applications for the user
  • Requires valid JWT and API key

GET /apps/:appId

  • Gets application details
  • Requires valid JWT and API key

PUT /apps/:appId

  • 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
    	}
    }

DELETE /apps/:appId

  • Deletes an application
  • Requires valid JWT and API key

GET /apps/:appId/stats

  • Gets request statistics for an application
  • Requires valid JWT and API key

Proxy

ANY /apis/:appId/*

  • Proxies requests to the target API
  • Requires valid API key
  • Rate limited based on application settings

GET /apis/status/:requestId

  • Checks the status of a queued request
  • Requires valid API key

Example Usage

1. Register a User

curl -X POST http://localhost:3000/users \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "password123",
    "organisationName": "My Org"
  }'

2. Login

curl -X POST http://localhost:3000/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "password123"
  }'

3. Create an Application

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
    }
  }'

4. Make a Proxied Request

curl -X GET http://localhost:3000/apis/YOUR_APP_ID/endpoint \

5. Check Request Status

curl -X GET http://localhost:3000/apis/status/YOUR_REQUEST_ID \

About

A scalable Rate Limiter Proxy API Service

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published