Регулирование вложенных запросов к роутам в Laravel

Для начала опишу задачу.

У нас имеется какой-то глобальный для группы запросов роут и в нем указан посредник throttle. Затем мы пытаемся добавить еще один throttle на внутренний для этой группы роут.

// User can send 1000 requests of any kind in an hour.
Route::prefix('image')->middleware('auth', 'throttle:1000,60')->group(function() {
    // User can download 10 times a minute.
    Route::post('/download', 'ImageController@download')->middleware('throttle:10,1');
    // User can search 100 times an hour
    Route::get('/search', 'ImageController@search')->middleware('throttle:100,60');
    // Use default throttle, user can send 1000 images in an hour.
    Route::get('/send', 'ImageController@send');
});

Тут мы ожидаем, что throttle внутреннего роута перезапишет верхний. Но мы удивимся, что маршрут блокируется после меньшего кол-ва запросов, чем ожидали. Почему так?

Я столкнулся с этой проблемой. И после некоторого раздумья я понял, что это действительно верное поведение – ведь посредник throttle на одном хите вызывается теперь дважды, и заголовок X-RateLimit-Remaining теперь уменьшается на два, а не на один. Но как нам преодолеть эту проблему?

  • Мы можем удалить глобальный посредник throttle и просто применить его на всех маршрутах, которые нам нужны. (Правда из-за этого будет довольно много повторений)
  • Возможно, мы можем переопределить посредника по умолчанию и реализовать какой-то идентификатор, который мы будем использовать для их различия.

К счастью, у Laravel уже есть решение для нас! К сожалению, в документации об этом ничего не говорится, однако все довольно просто – третьим параметром мы должны указать префикс нашего посредника.

// User can send 1000 requests of any kind in an hour.
Route::prefix('image')->middleware('auth', 'throttle:1000,60')->group(function() {
    // User can download 10 times a minute.
    Route::post('/download', 'ImageController@download')->middleware('throttle:10,1,minute_download');
    // User can search 100 times an hour
    Route::get('/search', 'ImageController@search')->middleware('throttle:100,60,search');
    // Use default throttle, user can send 1000 images in an hour.
    Route::get('/send', 'ImageController@send');
});

Вышеприведенная группа маршрутов включает в себя три маршрута внутри посредников auth и throttle. Эти два посредника можно рассматривать как глобальные для маршрутов внутри этой группы. В зависимости от сценария мы могли бы рассмотреть возможность применения различных значений throttle для некоторых маршрутов в группе. Это относится к маршрутам /download и /search – мы хотим иметь для них более низкий лимит запросов (в текущем случае). Мы достигаем этого, передавая третий аргумент посреднику. Это значение префикса, которое будет использоваться для их отличия – throttle:max_requests,period,prefix.

Эта функция была введена в Laravel 6.0. Для всех предыдущих версий, вам нужно переопределить Throttle по умолчанию и реализовать свое собственное решение.

https://ntsanov.com/blog/nested-request-throttling-in-laravel

Рейтинг
( 3 оценки, среднее 5 из 5 )
Maxyc Webber/ автор статьи
Мне 35 лет. Опыт профессиональной разработки 15 лет. Занимаюсь разработкой и поддержкой корпоративных систем автоматизации бизнеса, а также высоконагруженными проектами. Мне нравится решать нестандартные проблемы бизнеса. Имею опыт формирования команд под проект, налаживания процесса разработки, коммуникации программистов и заказчиков. Есть опыт работы с зарубежными заказчиками (ОАЭ, Польша, Германия, Швейцария).
Понравилась статья? Поделиться с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!:

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.