artisansdk/ratelimiter
ArtisanSDK RateLimiter is a Laravel/PHP package for adding configurable request throttling to your app. Define limits per route or key, enforce rate rules, and protect APIs from abuse with simple integration and clear control over retry/decay 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?