Один із методів магії
Обмежувач швидкості повинен бути однією з найбільш непомічених функцій у Laravel. Для тих, хто новачок в Rate Limiter, суть його проста для розуміння: «оцінювати» щось, виходячи з максимальної кількості спроб всередині вікна часу.
Звичайна і найпоширеніша процедура використання обмежувача швидкості полягає в тому, щоб, по-перше, перевірити, чи не було зроблено занадто багато спроб ключа. Якщо цей ключ є в наявності, тільки тоді ми переходимо до виконання нашої логіки. Нарешті, ми збільшуємо кількість спроб по вікні часу до «розпаду».
Це, по суті, двоетапна логіка.
Вищесказане перекладається в «Якщо foo
ключ був зроблений більше 5 разів, поверніть що-небудь. В іншому випадку виконуйте логіку, і збільшуйте foo
спроби протягом наступних 60 секунд».
Іншими словами, якщо зробити спробу ключа foo
більше 5 разів за 60 секунд, tooManyAttempts()
то повернеться true
і нічого не буде виконано.
Вищесказане працює нормально більшу частину часу, але замість того, щоб викликати обмежувач швидкості двічі, з одним і тим же ключем, і залишивши логіку між двома дзвінками, ми можемо зробити щось більш просте.
Мені подобається один лайнер, і я зовсім недавно отримав схвалення маленького помічника під назвою attempt()
, який повинен приземлитися в Laravel 8.53. Те, що він робить, - це те ж саме, але за допомогою зворотного дзвінка, і з тим же замовчуванням 60 секунд. Наш приклад, наведений вище, можна відновити лише в умовному твердженні:
Оскільки він отримує a Closure
, обмеження ставки може стати портативним. Наприклад, ви можете зберегти функцію на початку та виконати її пізніше, замість того, щоб одружувати обмеження, що обмежує швидкість, на все, що у вас є між перевіркою та хітом. В якості альтернативи ви завжди можете використовувати a callable
за допомогою Closure::fromCallable()
.
Найкраща реалізація полягає у attempt()
створенні ідемпотентних викликів. Наприклад, уявіть, що ми хочемо надіслати повідомлення користувачеві, але пропустіть всю логіку, якщо повідомлення точно таке ж, яке він надіслав менше 2 хвилин тому. Це може статися, якщо з'єднання нестабільне, або коли користувач випадково натискає «Надіслати» занадто багато разів.
Немає проблем, ми можемо отримати хеш повідомлення як ключ, а потім перевірити, чи було воно надіслано раніше.
Останнє круте в attempt()
тому, що він поверне результат зворотного дзвінка. Коли зворотний дзвінок нічого не повертає, або null
, attempt()
повернеться true
.
Наприклад, якщо ми хочемо повернути модель, не проблема. Якщо зворотний дзвінок не був виконаний через те, що він досяг ліміту ставки, то false
завжди повертається.