Один из магических методов
Ограничитель скорости должен быть одной из самых упускаемых из виду функций в Laravel. Для тех, кто новичок в Rate Limiter, суть его проста для понимания: «ограничить скорость» чего-то на основе максимального количества попыток внутри окна времени.
Обычная и наиболее распространенная процедура использования ограничителя скорости заключается в том, чтобы, во-первых, проверить, не был ли ключ предпринят слишком много раз. Если этот ключ доступен, только тогда мы приступаем к выполнению нашей логики. Наконец, мы увеличиваем количество попыток вдоль окна времени «загнить».
Это в основном двухэтапная логика.
Вышесказанное переводится как «Если foo
ключ был предпринят более 5 раз, верните что-нибудь. В противном случае выполните логику и увеличьте foo
попытки в течение следующих 60 секунд».
Другими словами, если foo
ключ будет предпринят более 5 раз за 60 секунд, он tooManyAttempts()
вернется true
, и ничего не будет выполнено.
Вышесказанное работает нормально большую часть времени, но вместо того, чтобы вызывать Rate Limiter два раза, с одним и тем же ключом, и оставлять логику между двумя вызовами, мы можем сделать что-то более простое.
Мне нравятся однолинейные, и я совсем недавно получил одобрение маленького помощника под названием attempt()
, который должен приземлиться в Laravel 8.53. То, что он делает, это то же самое, но с использованием обратного вызова и с тем же значением по умолчанию 60 секунд. Наш пример выше можно возобновить только в условном операторе:
Поскольку он получает a Closure
, ограничение скорости может стать переносимым. Например, вы можете сохранить функцию в начале и выполнить ее позже, вместо того, чтобы объединять ограничение скорости с тем, что у вас есть между проверкой и хитом. В качестве альтернативы вы всегда можете использовать a callable
с помощью Closure::fromCallable()
.
Лучшая реализация attempt()
— для создания идемпотентных вызовов. Например, представьте, что мы хотим отправить сообщение пользователю, но пропускаем всю логику, если сообщение точно такое же, которое он отправил менее 2 минут назад. Это может произойти, если соединение нестабильно, или когда пользователь нажимает «Отправить» слишком много раз случайно.
Нет проблем, мы можем получить хэш сообщения в качестве ключа, а затем проверить, было ли оно отправлено ранее.
Последнее, что интересно, это то attempt()
, что он вернет результат обратного вызова. Когда обратный звонок ничего не возвращает, или null
, attempt()
вернется true
.
Например, если мы хотим вернуть модель, нет проблем. Если обратный вызов не был выполнен, потому что он достиг предела скорости, то false
он всегда возвращается.