Jump to content

Programming Challenge: Enterprise API Rate Limiting System (Jan 26, 2025)

Featured Replies

Posted

Challenge:

Design and implement an API rate-limiting system that prevents abuse and ensures fair usage of enterprise APIs. The system should allow different rate limits based on user roles (e.g., Free, Premium, Admin) and IP addresses.

Basic Requirements:

Implement request counting to track API usage per user/IP.
Set rate limits (e.g., 100 requests per minute for Free users, 1,000 for Premium).
Block or throttle users exceeding their limit.
Use an in-memory store (e.g., Redis, Python Dictionary) to track API usage.

Bonus Features for Enterprise-Grade Security:

🔹 Role-Based Rate Limits: Different limits for Free, Premium, and Admin users.
🔹 Sliding Window Algorithm: Prevents burst attacks while allowing fair access.
🔹 Distributed Rate Limiting: Use Redis or a database to track limits across multiple servers.
🔹 JWT Authentication: Verify user roles with OAuth2/OpenID Connect.
🔹 Real-Time Monitoring: Generate logs and alerts when users exceed limits.
🔹 IP Whitelisting & Blacklisting: Allow or block specific IPs dynamically.

Example Implementation (Python + Flask + Redis)

from flask import Flask, request, jsonify
import time
import redis

app = Flask(__name__)
r = redis.Redis(host='localhost', port=6379, db=0)

# Define rate limits
RATE_LIMITS = {
    "free": 100,    # 100 requests per minute
    "premium": 1000,
    "admin": 5000
}

def is_rate_limited(user_id, role):
    key = f"rate:{user_id}"
    current_time = int(time.time() / 60)  # Minute-based window

    # Get current request count
    user_data = r.hgetall(key)
    if user_data and int(user_data[b'timestamp']) == current_time:
        if int(user_data[b'count']) >= RATE_LIMITS.get(role, 100):  
            return True
        else:
            r.hincrby(key, "count", 1)
    else:
        r.hmset(key, {"count": 1, "timestamp": current_time})

    return False

@app.route("/api/resource")
def api_resource():
    user_id = request.headers.get("User-ID", "anonymous")
    user_role = request.headers.get("User-Role", "free")  

    if is_rate_limited(user_id, user_role):
        return jsonify({"error": "Rate limit exceeded"}), 429

    return jsonify({"message": "Success!"})

if __name__ == "__main__":
    app.run(debug=True)
  • Views 140
  • Created
  • Last Reply

Create an account or sign in to comment

Important Information

Terms of Use Privacy Policy Guidelines We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.