Laravel Quota — це пакет для відстеження та контролю лімітів використання ресурсів. З його допомогою можна налаштувати обмеження на кшталт 50 експортів PDF на місяць, 1000 API-запитів на день або виділити пул AI-кредитів на розрахунковий період.
На відміну від стандартного RateLimiter у Laravel, який обмежує піковий трафік у «ковзному вікні» (throttling), Quota рахує споживання в межах бюджету, прив'язаного до календарних меж. Крім того, дані можна зберігати не лише в кеші, а й у базі даних.
Основні можливості пакета:
- Календарні періоди — налаштовуйте ліміти через
perMinute(),perHour(),perDay(),perWeek(),perMonth(),perYear()або задавайте власні межі черезperiod($start, $end). - Трейт
HasQuotas— додає підтримку квот до будь-якої Eloquent моделі. - Route middleware (
quota:exports,50,month) — автоматично списує квоту лише після успішної відповіді сервера. - Гнучкість сховищ — перемикайтеся між кешем та базою даних для кожного окремого виклику.
- Атомарне споживання — використання блокувань (locks) для запобігання помилок при одночасних запитах.
- Контроль бюджету — автоматичне повернення помилки HTTP 429, коли ліміт вичерпано.
- Та багато іншого.
# Fluent API
Квота — це іменований лічильник, прив'язаний до власника, з визначеним лімітом і періодом. Після створення її можна перевіряти або використовувати для списання ресурсів:
use ZaberDev\Quota\Facades\Quota;
$builder = Quota::for('api_queries', $user)
->limit(1000)
->perDay();
$builder->used();
$builder->remaining();
$builder->isExceeded();
$builder->hasCapacity(10);
$info = $builder->consume(5);
Метод consume() повертає незмінний QuotaInfo DTO. Якщо ви хочете переривати виконання коду за браком ліміту, використовуйте enforce() — він видасть HTTP 429, якщо бюджет вичерпано:
Quota::for('api_queries', $user)->limit(1000)->perDay()->enforce();
Для критичних операцій, де важливо уникнути подвійного списання, метод block() огортає callback у lock-механізм. Це гарантує, що два паралельні запити не пройдуть перевірку залишку одночасно:
Quota::for('pdf_generation', $user)
->limit(50)
->perMonth()
->block(function () use ($pdfService) {
$pdfService->generate();
}, amount: 1, lockSeconds: 30);
# Квоти в моделях Eloquent
Додайте трейт HasQuotas, щоб працювати з лімітами безпосередньо через модель:
use ZaberDev\Quota\HasQuotas;
class User extends Authenticatable
{
use HasQuotas;
}
$user->quota('pdf_exports')->limit(25)->perMonth()->consume();
$user->quota('pdf_exports')->limit(25)->perMonth()->remaining();
При використанні бази даних записи є поліморфними, тому квоти можна отримувати як звичайні зв'язки (relations):
$activeQuotas = $user->quotas()
->where('period_end', '>', now())
->get();
# Middleware для маршрутів
Middleware quota приймає назву, ліміт, період та опціональний драйвер:
Route::post('/exports/generate', [ExportController::class, 'store'])
->middleware('quota:exports,50,month');
Route::post('/api/v1/query', [ApiController::class, 'query'])
->middleware('quota:api_query,1000,day,database');
Логіка роботи: наявність ліміту перевіряється до виконання маршруту, але фактичне списання відбувається лише якщо сервер повернув відповідь 2xx або 3xx. Якщо запит закінчився помилкою 500 або не пройшов валідацію, квота користувача залишається незмінною.
# Сховища даних
Драйвером за замовчуванням є cache (підтримуються Redis та Memcached). Драйвер database записує дані в таблицю quotas. Це оптимальний вибір, коли ліміти пов'язані з білінгом і не мають зникнути після очищення кешу. Драйвер можна вказувати для кожного виклику:
Quota::for('api_ping', $ip)->using('cache')->limit(5000)->perDay()->consume();
Quota::for('monthly_exports', $user)->using('database')->limit(50)->perMonth()->consume();
За допомогою Quota::extend() можна зареєструвати власний драйвер. Очищення застарілих записів у базі даних можна автоматизувати за розкладом:
use ZaberDev\Quota\Models\Quota;
Schedule::command('model:prune', ['--model' => Quota::class])->daily();
# Встановлення
Пакет вимагає PHP 8.2+ та підтримує Laravel 11, 12 і 13:
composer require zaber-dev/laravel-quota
php artisan vendor:publish --provider="ZaberDev\Quota\QuotaServiceProvider"
php artisan migrate
У файлі конфігурації config/quotas.php можна змінити драйвер (QUOTA_DRIVER), налаштувати параметри кешу, назву таблиці в БД та диспетчеризацію подій.
Детальна документація доступна на GitHub.