artisansdk/ratelimiter
Laravel rate limiting package providing flexible throttling for routes and actions with configurable rules, storage drivers, and easy middleware integration. Helps protect APIs from abuse, control request bursts, and manage per-user or per-IP limits with clear, adjustable settings.
Installation
composer require artisansdk/ratelimiter
Publish the config file:
php artisan vendor:publish --provider="ArtisanSDK\RateLimiter\RateLimiterServiceProvider"
Basic Configuration
Edit config/ratelimiter.php to define default limits (e.g., max_attempts=100, decay_seconds=1).
Example route-level limit:
Route::get('/api/endpoint', function () {
return response()->json(['data' => 'protected']);
})->middleware('ratelimit:api,100,1'); // 100 requests per minute
First Use Case Apply the middleware to a route or group:
Route::middleware(['ratelimit:api,100,1'])->group(function () {
Route::get('/user', 'UserController@index');
Route::post('/user', 'UserController@store');
});
Test with curl or Postman to verify throttling behavior.
Route::get('/api/{resource}', function ($resource) {
return response()->json(['data' => $resource]);
})->middleware('ratelimit:api,100,1')->name('api.resource');
Override in ratelimiter.php:
'limits' => [
'api' => [
'default' => ['max_attempts' => 100, 'decay_seconds' => 1],
'resource' => ['max_attempts' => 50, 'decay_seconds' => 1], // Override for `/api/resource`
],
],
namespace App\Http\Middleware;
use ArtisanSDK\RateLimiter\Middleware\RateLimitMiddleware;
class CustomRateLimitMiddleware extends RateLimitMiddleware {
protected function resolveLimit($request) {
return $request->user()->rate_limit ?? config('ratelimiter.limits.api.default');
}
}
Register in app/Http/Kernel.php:
protected $routeMiddleware = [
'ratelimit.custom' => \App\Http\Middleware\CustomRateLimitMiddleware::class,
];
// Manually check a request (e.g., in a controller)
$limit = config('ratelimiter.limits.api.default');
$key = 'api|' . $request->ip();
if (!RateLimiter::try($key, $limit['max_attempts'], $limit['decay_seconds'])) {
return response()->json(['error' => 'Too many requests'], 429);
}
ratelimiter.php:
'cache' => [
'driver' => 'redis', // Supports 'file', 'database', 'redis', etc.
'key_prefix' => 'ratelimiter_',
],
For Redis, ensure the predis/predis package is installed.ip() alone may not suffice for shared IPs). Use:
$key = 'api|' . $request->ip() . '|' . $request->user()->id;
ratelimit before authentication middleware if limiting unauthenticated requests.ratelimiter.php:
'log_exceeded' => true,
Check storage/logs/laravel.log for throttled attempts.php artisan ratelimiter:test to simulate rate limits.ArtisanSDK\RateLimiter\Contracts\RateLimiterStorage for custom backends (e.g., database).ratelimit.exceeded events:
event(new RateLimitExceeded($request, $key, $limit));
decay_seconds per route or user:
Route::get('/premium', function () {
// 10 requests per 5 seconds for premium users
})->middleware('ratelimit:premium,10,5');
max_attempts or decay_seconds in ratelimiter.php to inherit global defaults.'limits' => [
'api' => [
'default' => [
'max_attempts' => env('RATE_LIMIT_MAX', 100),
'decay_seconds' => env('RATE_LIMIT_DECAY', 1),
],
],
],
How can I help you explore Laravel packages today?