Важливо: у Laravel 11-13 група middleware api за замовчуванням не обмежує частоту запитів. Обмеження треба ввімкнути явно.
1. Визначити лімітер (в AppServiceProvider::boot()):
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
2. Підключити - для всієї групи api:
// bootstrap/app.php
->withMiddleware(function (Middleware $middleware): void {
$middleware->throttleApi(); // throttle:api для групи api
// $middleware->throttleApi(redis: true);
})
або точково на маршрутах: ->middleware('throttle:api').
Різні ліміти для різних клієнтів і дій:
RateLimiter::for('api', function (Request $request) {
$user = $request->user();
return match (true) {
$user === null => Limit::perMinute(30)->by($request->ip()),
$user->isPremium() => Limit::perMinute(600)->by($user->id),
default => Limit::perMinute(120)->by($user->id),
};
});
RateLimiter::for('login', fn (Request $request) => [
Limit::perMinute(500), // загальний для ендпойнта
Limit::perMinute(5)->by($request->input('email').'|'.$request->ip()),
]);
RateLimiter::for('exports', fn (Request $request) => Limit::perDay(10)->by('exports:'.$request->user()->id));
Що отримує клієнт: при перевищенні - 429 Too Many Requests із заголовками Retry-After і X-RateLimit-Limit/X-RateLimit-Remaining. Власна відповідь - Limit::perMinute(60)->response(...).
Що враховувати:
- ключ (
by) визначає, кого рахувати: користувача, IP, токен, організацію. Для кількох лімітів з однаковим ключем - префікси ('minute:'.$id,'day:'.$id), інакше лічильники змішаються; - IP за проксі - Laravel має довіряти проксі (
trustProxies), інакше всі клієнти матимуть IP балансувальника й поділять один ліміт; - сховище лічильників - кеш застосунку. На кількох серверах потрібен спільний кеш (Redis),
throttleApi(redis: true)використовує ефективніший Redis-middleware; - дорогі ендпойнти (пошук, експорт, генерація звітів) - окремі суворіші лімітери, а не один на все API;
- ліміти на рівні CDN/WAF (Cloudflare) - перший рубіж від масових атак; лімітери застосунку - для справедливого розподілу між клієнтами.
Тестування: RateLimiter::clear($key) між тестами або перевірка 429 на N+1-му запиті.