В последнее время я всё чаще и чаще работаю над созданием API при разработке на Laravel. Я использую свой класс для ручного ограничения скорости запросов, но мне всегда казалось, что для этого есть более простое решение. И не удивительно, что когда Тэйлор собрался написать посредник для ограничения скорости запросов, то у него это вышло проще и лучше, чем у меня.
Это одна из статей о новых функциях Laravel 5.2. Скоро будут ещё, не пропустите.
- Проверка массива формы в Laravel 5.2
- Неявная привязка модели маршрута в Laravel 5.2
- Ограничение скорости запросов API в Laravel 5.2
- Заготовка авторизации в Laravel 5.2
- Множественные драйверы защиты авторизации (включая API) в Laravel 5.2
Краткое введение в ограничение скорости запросов
Если вы ещё не знакомы с ним, то ограничение скорости — это часто используемый в API инструмент, который ограничивает скорость запросов для каждого отдельного запрашивающего.
Это означает, например, если какой-нибудь бот обращается к довольно затратному API-маршруту тысячу раз в минуту, ваше приложение не упадёт, потому что после n-й попытки он получит от сервера ответ 429: Too Many Attempts (слишком много попыток).
Обычно хорошо написанное приложение, использующее ограничение скорости, в отличие от других приложений будет также возвращать три заголовка: X-RateLimit-Limit, X-RateLimit-Remaining и Retry-After (если вы достигните предела, то получите только Retry-After). X-RateLimit-Limit — это максимальное число запросов для приложения, разрешённое в данном интервале времени. X-RateLimit-Remaining — это сколько запросов у вас осталось в данном интервале времени. А Retry-After — это сколько секунд надо ждать до следующей попытки. (Retry-After может быть не количеством секунд, а датой).
Каждый API выбирает свой интервал времени для ограничения. У GitHub он равен часу, у Twitter — 15 минут. У данного посредника Laravel — 1 минута.
Как использовать посредник для ограничения скорости запросов Laravel
Рассмотрим новую возможность Laravel 5.2. Появился новый посредник throttle. Посмотрим на нашу группу API:
Route::group(['prefix' => 'api'], function () {
Route::get('people', function () {
return Person::all();
});
});
Применим к ней throttle. По умолчанию его предел — 60 попыток в минуту, ограничение длится в течение той минуты, когда достигнут предел.
Route::group(['prefix' => 'api', 'middleware' => 'throttle'], function () {
Route::get('people', function () {
return Person::all();
});
});
Теперь при запросе к этому маршруту api/people вы увидите такие строчки в заголовках ответов:
HTTP/1.1 200 OK ... other headers here ... X-RateLimit-Limit: 60 X-RateLimit-Remaining: 59
Запомните, этот ответ значит:
а) этот запрос успешный (статус 200)
б) вы можете обращаться к этому маршруту со скоростью 60 раз в минуту
в) у вас осталось 59 запросов в этой минуте
Какой ответ мы получим, если достигнем предела:
HTTP/1.1 429 Too Many Requests ... other headers here ... Retry-After: 60 X-RateLimit-Limit: 60 X-RateLimit-Remaining: 0
И содержимым ответа будет строка: Too Many Attempts. (слишком много попыток).
А если попробовать через 30 секунд?
HTTP/1.1 429 Too Many Requests
... other headers here ...
Retry-After: 30
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
Тот же ответ, только таймер Retry-After, означающий сколько надо подождать, уже на отметке 30.
Настройка посредника throttle
Давайте немного настроим. Сделаем ограничение на 5 попыток в минуту.
Route::group(['prefix' => 'api', 'middleware' => 'throttle:5'], function () {
Route::get('people', function () {
return Person::all();
});
});
А теперь сделаем так, что если кто-то достигнет предела, то ему надо будет ждать 10 минут.
Route::group(['prefix' => 'api', 'middleware' => 'throttle:5,10'], function () {
Route::get('people', function () {
return Person::all();
});
});
Код вы можете найти здесь: ThrottlesRequests.php.
Комментарии (2)
Ограничение скорости Laravel — отличная возможность в Laravel контролировать количество обращений.
А можно использовать 2 посредника, например первый throttle:5,1 а второй throttle:20,60 ?
Потому что пользователи часто чтото быстро делают за короткий промежуток времени потом отдыхают, потом опять чтото поделал и так несколько раз за большой промежуток времени. Надеюсь вы поняли о чём я.