A sliding rate limiter using Redis. This package depends on moment/luxon and luin/ioredis.
We don't recommend consuming this package in plain JavaScript (to be able to use interfaces).
Inspired by these blogposts:
- https://engagor.github.io/blog/2017/05/02/sliding-window-rate-limiter-redis/
- https://engagor.github.io/blog/2018/09/11/error-internal-rate-limit-reached/
You can use your package manager (npm
or yarn
) to install:
npm install --save @journyio/ratelimiter
or
yarn add @journyio/ratelimiter
import Client from "ioredis";
import { Duration } from "luxon";
import { RateLimiter, RateLimiterRedis, RateLimitedResource } from "@journyio/ratelimiter";
import { ClockSystem } from "@journyio/clock";
class API {
constructor(private readonly rateLimiter: RateLimiter) {}
async getUser(id: UserId) {
const resource = new RateLimitedResource(
`API-calls-user-${id}`,
100,
Duration.fromObject({ minute: 1 })
);
const allowed = await this.rateLimiter.consume(resource);
if (!allowed) {
throw new Error("Rate limited!");
}
/* ... */
}
}
const redis = new Client(process.env.REDIS_URL)
const rateLimiter = new RateLimiterRedis(redis, new ClockSystem());
const api = new API(rateLimiter);
const user = await api.getUser(/* ... */);
const resource = new RateLimitedResource(
"API-calls-user-1313",
100,
Duration.fromObject({ minute: 1 })
);
const allowed = await this.rateLimiter.consume(resource);
const remainingCalls = await rateLimiter.remaining(resource);
await rateLimiter.reset(resource);
To run the tests:
npm run test
(assuming redis runs on port 6379)
If you discover any security related issues, please email security at journy io instead of using the issue tracker.