• Reading time ~ 2 min
  • 04.07.2022

 

One method magic

 

Photo by Jad Limcaco on Unsplash

The Rate Limiter should be one of the most overlooked features in Laravel. For those who are new to the Rate Limiter, the gist of it is simple to understand: to “rate limit” something based on the maximum number of attempts inside a window of time.

The normal and most common procedure to use the Rate Limiter is to, first, check if a key as been attempted too many times. If this key is available, only then we proceed to execute our logic. Finally, we increment the number of attempts along the window of time to “decay”.

This is basically a two-step logic.

The above translates in “If the foo key has been attempted more than 5 times, return something. Otherwise, execute the logic, and increment the foo attempts for the next 60 seconds”.

In other words, if the foo key is attempted more than 5 times in 60 seconds, the tooManyAttempts() will return true and nothing will be executed.

The above works fine most of the time, but instead having to calling the Rate Limiter two times, with the same key, and leaving the logic between the two calls, we can do something more straightforward.

I like oneliners, and I just recently got approved a little helper called attempt(), that should land in Laravel 8.53. What it does is the same thing, but using a callback, and with the same default of 60 seconds. Our example above can be resumed in just a conditional statement:

Since it receives a Closure, the Rate Limiting can become portable. For example, you can save a function in the beginning and execute it later, instead of marrying the rate limiting to whatever you have between the check and the hit. As an alternative, you can always use a callable by using Closure::fromCallable().

The best implementation of the attempt() is for creating idempotent calls. For example, imagine we want to message an user, but skip the whole logic if the message is exactly the same he sent less than 2 minutes ago. That may happen if the connection is unstable, or when the user presses “Send” too many times accidentally.

No problem, we can get a hash of the message as the key and then check if it was sent previously.

The last cool thing about attempt() is that it will return the callback result. When the callback doesn’t return anything, or null, the attempt() will return true.

For example, if we want to return a model, no problem. If the callback wasn’t executed because it reached the rate limit, then false is always returned.

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

ABOUT

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

About author CrazyBoy49z
WORK EXPERIENCE
Contact
Ukraine, Lutsk
+380979856297