Laravel Quota: бюджети використання за календарні періоди

Перекладено ШІ 0 Laravel News 15 липня, 2026

Пакет Laravel Quota дозволяє легко налаштовувати ліміти на використання ресурсів із прив’язкою до календарних періодів. Це гнучке рішення підтримує збереження даних у базі або кеші та пропонує зручний Fluent API для вашого проєкту.

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.

Популярні

Інше, що варто прочитати

17 Оновлено 26 червня, 2026

Обробка геопросторових даних за допомогою Laravel Magellan

Ви готові відкрити нові горизонти у роботі з геопросторовими даними в Laravel? Дізнайтеся, як за допомогою PostGIS та пакету Laravel-Magellan можна легко зберігати, запитувати та маніпулювати інформацією про розташування, перетворюючи ваші проекти на вражаючі рішення у сфері картографії та геолокації!

14 Оновлено 26 червня, 2026

Як задокументувати кілька API в Laravel за допомогою Scramble

Ви знали, що в одному додатку Laravel можна реалізувати кілька API? У нашій статті ви дізнаєтеся, як за допомогою Scramble легко документувати різні версії API та налаштувати доступ до документації, щоб зробити її публічною або приватною. Читайте далі, щоб дізнатися більше

10 Оновлено 26 червня, 2026

Остаточний посібник з вебхуків у Laravel

Сучасні веб-додатки вимагають миттєвого обміну інформацією, і вебхуки стають незамінними помічниками у цьому процесі. Пориньте у світ вебхуків у Laravel і дізнайтеся, як легко реалізувати цю технологію у своїх проєктах, забезпечуючи безпеку та продуктивність