Add a way to check the status of rate limiters without incrementing them
Prerequisites
- [x] I have written a descriptive issue title
- [x] I have searched existing issues to ensure the feature has not already been requested
🚀 Feature Proposal
After creating a rate limiter manually using fastify.createRateLimit(), I can call this limiter as a function. However, this also increments the limiter. I would like a way to just check the current status of the rate limiter without incrementing it.
Here's an example syntax of how it might work:
// Create manual rate limiter
const checkRateLimit = fastify.createRateLimit();
// Check status and increment limiter, like it works today
const limit = await checkRateLimit(request);
// Proposal to only check status without increment. Returns the same as above, but doesn't change the "remaining" property.
const limit = await checkRateLimit(request, { increment: false });
The reason I need this is because I want to apply a rate limiter to my login endpoint specifically, but only want it incremented when the login attempt fails. I still need to check if my limiter has been reached regardless of success/failure, so that I can deny access if it's reached, which is why I need this feature.
Another solution would be a way to reset/modify the "remaining" property manually, so I could reset it when the user successfully logins. Whichever solution is fine by me, but I figured that the ability to check status of a limiter without incrementing it might also be useful for other purposes, such as monitoring.
Motivation
No response
Example
No response
The reason I need this is because I want to apply a rate limiter to my login endpoint specifically, but only want it incremented when the login attempt fails.
I am not opposed to giving users of the plugin a way to check the current status of rate limiting without incrementing, but I am not convinced that your motivation is relevant. You could check rate limit only on authentication failure, you just have to adapt the configuration to this behavior.
But like I said, ok for this feature.
If @fastify/plugins agrees, you will have to push a PR with unit tests.
Somehow ok with this.
But imho we should think about potential implementations by the devs.
E.g. if we provide this functionality, does this not mean, that we maybe want a way to expose this information to the client?
Github has a GET /rate_limit endpoint. Also they have a secondary rate limitter in place even for that endpoint.
Also see the endpoint documentation:
https://docs.github.com/en/rest/rate-limit/rate-limit?apiVersion=2022-11-28#get-rate-limit-status-for-the-authenticated-user
So is there maybe a bigger potential in this topic?
Should we maybe track the rateLimitters in an Object and make it required to give the rateLimtter a name? So when we want the information, we can provide the request to the rateLimitters and then get the values?
Should we maybe track the rateLimitters in an Object and make it required to give the rateLimtter a name? So when we want the information, we can provide the request to the rateLimitters and then get the values?
I like the idea, maybe we should decorate the instance with a rateLimiters Map:
const rateLimiter = fastify.rateLimiters.get('authentication');
const limit = await rateLimiter.read(request);
// Or
rateLimiter.increment(request);
make it required to give the rateLimtter a name
Required or optional, we could generate a random name by default.
We can encapsulate { increment: false } to offer a clean public api (e.g. read and increment, or whatever).
Hi, stumbled upon this thread while I was looking for a similar solution. In my case I need to increment the counter for valid (200) responses, but enforce the rate limit before executing the logic (without incrementing).
It sounds like the solution where I can read the counter without incrementing would be helpful here.
@fastify/core
Because only one answer from plugin team.
SGTM, it can be very beneficial, especially when attempting to apply limits to custom workflows or according to business logic