Need help with async-ratelimiter?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

microlinkhq
223 Stars 17 Forks MIT License 67 Commits 2 Opened issues

Description

Rate limit made simple, easy, async.

Services available

!
?

Need anything else?

Contributors list

# 10,408
Ruby
nextjs
Algolia
algolia...
40 commits
# 149,931
hapijs
adonisj...
CSS
Angular
3 commits
# 180,849
memoiza...
js
React
C++
2 commits
# 19,453
SQL
spotify
raspbia...
alsa
1 commit
# 741,372
JavaScr...
1 commit
# 176
nextjs
postman...
graphql...
angular...
1 commit
# 721,646
JavaScr...
1 commit
# 105,358
HTML
yarn
npm
React
1 commit
microlink

Last version Build Status Coverage Status Dependency status Dev Dependencies Status NPM Status

Rate limit made simple, easy, async. Based on ratelimiter.

Install

$ npm install async-ratelimiter --save

Usage

A simple middleware implementation for whatever HTTP server:

'use strict'

const RateLimiter = require('async-ratelimiter') const { getClientIp } = require('request-ip') const Redis = require('ioredis')

const rateLimiter = new RateLimiter({ db: new Redis() })

const apiQuota = async (req, res, next) => { const clientIp = getClientIp(req) const limit = await rateLimiter.get({ id: req.clientIp })

if (!res.finished && !res.headersSent) { res.setHeader('X-Rate-Limit-Limit', limit.total) res.setHeader('X-Rate-Limit-Remaining', Math.max(0, limit.remaining - 1)) res.setHeader('X-Rate-Limit-Reset', limit.reset) }

return !limit.remaining ? sendFail({ req, res, code: HTTPStatus.TOO_MANY_REQUESTS, message: MESSAGES.RATE_LIMIT_EXCEDEED() }) : next(req, res) }

API

constructor(options)

It creates an rate limiter instance.

options

db

Required
Type:

object

The redis connection instance.

max

Type:

number

Default:
2500

The maximum number of requests within

duration
.
duration

Type:

number

Default:
3600000

How long keep records of requests in milliseconds.

namespace

Type:

string

Default:
'limit'

The prefix used for compound the key.

id

Type:

string

The identifier to limit against (typically a user id).

You can pass this value using when you use

.get
method as well.

.get(options)

Given an

id
, returns a Promise with the status of the limit with the following structure: -
total
:
max
value. -
remaining
: number of calls left in current
duration
without decreasing current
get
. -
reset
: time since epoch in seconds that the rate limiting period will end (or already ended).

options

id

Type:

string
Default:
this.id

The identifier to limit against (typically a user id).

max

Type:

number
Default:
this.max

The maximum number of requests within

duration
. If provided, it overrides the default
max
value. This is useful for custom limits that differ between IDs.
duration

Type:

number
Default:
this.max

How long keep records of requests in milliseconds. If provided, it overrides the default

duration
value.
decrease

Type:

boolean
Default:
true

When set to

false
, the remaining number of calls is not decreased.

In some scenarios it might be useful to be able to read the current "remaining" value for a limiter.

const loginHandler = async (req, res, next) => {
  const clientIp = getClientIp(req)
  const limit = await rateLimiter.get({ id: clientIp, decrease: false })

if (!limit.remaining) return sendError(req, res, 429)

try { await doLogin(req) } catch (err) { if (err) { await rateLimiter.get({ id: req.clientIp }) return sendError(req, res, 401) } }

next(req, res) }

In this example, new login attempts are rejected when more at least 10 unsuccessful login attempts happened in the last 60 seconds.

Related

  • express-slow-down – Slow down repeated requests; use as an alternative (or addition) to express-rate-limit.

License

async-ratelimiter © microlink.io, released under the MIT License.
Authored and maintained by microlink.io with help from contributors.

microlink.io · GitHub microlink.io · Twitter @microlinkhq

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.