This is a continuation of Laravel API uses Redis+Lua for request throttling
Let’s extend the Redis + Lua rate limiter so different API endpoints can have different limits and windows.
1. Update the Service to Support Endpoint Keys
In app/Services/RateLimiter.php:
php
<?php
namespace App\Services;
use Illuminate\Support\Facades\Redis;
class RateLimiter
{
public static function attempt(string $userId, string $endpoint, int $limit, int $window): bool
{
$script = file_get_contents(app_path('Services/Redis/rate_limit.lua'));
// Key includes both user and endpoint
$key = "rate_limit:{$endpoint}:{$userId}";
$result = Redis::eval($script, 1, $key, $limit, $window);
return $result === 1;
}
}
2. Example Usage in a Controller
In app/Http/Controllers/ApiController.php:
php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Services\RateLimiter;
class ApiController extends Controller
{
public function login(Request $request)
{
$userId = $request->ip(); // for login, limit by IP
// Stricter: 3 attempts per 60 seconds
if (!RateLimiter::attempt($userId, 'login', 3, 60)) {
return response()->json(['error' => 'Too Many Login Attempts'], 429);
}
return response()->json(['message' => 'Login successful']);
}
public function profile(Request $request)
{
$userId = $request->user()->id ?? $request->ip();
// Looser: 20 requests per 60 seconds
if (!RateLimiter::attempt($userId, 'profile', 20, 60)) {
return response()->json(['error' => 'Too Many Profile Requests'], 429);
}
return response()->json(['profile' => ['name' => 'Phillip', 'age' => 30]]);
}
}
3. Redis Keys That Will Be Created
rate_limit:login:192.168.1.5→ 3 per 60srate_limit:profile:42→ 20 per 60s
Each endpoint has its own counter per user/IP, so limits are independent.
Benefits:
- Fine-grained control (e.g., stricter on login, looser on browsing).
- Easy to add more endpoints with different rules.
- Scales horizontally (works across multiple app servers).
You can also make this configurable in a single place (like a config/rate_limits.php file), so you don’t hardcode limits in every controller. See Laravel: creating config file for rate limits.

