Awesome
thunk-ratelimiter
The fastest abstract rate limiter.
thunks
Implementations:
- smart-limiter Smart rate limiter middleware for express.
- toa-ratelimit Smart rate limiter module for toa.
Requirements
- Redis 2.8+
Installation
npm install thunk-ratelimiter
Example
Example Connect middleware implementation limiting against a user._id
:
const limiter = new Limiter()
limiter.connect(redisClient) // connect to a thunk-redis instance
limiter.get(req.user._id).then(function (limit) {
response.set('X-RateLimit-Limit', limit.total)
response.set('X-RateLimit-Remaining', limit.remaining)
response.set('X-RateLimit-Reset', Math.ceil(limit.reset / 1000))
// all good
debug('remaining %s/%s %s', limit.remaining, limit.total, id)
if (limit.remaining >= 0) return
// not good
let after = Math.ceil((limit.reset - Date.now()) / 1000)
response.set('Retry-After', after)
response.end(429, 'Rate limit exceeded, retry in ' + after + ' seconds')
})
API
new Limiter(options)
Return a limiter instance.
const limiter = new Limiter()
options.max
: Optional, Type:Number
, max requests withinduration
, default to2500
.options.duration
: Optional, Type:Number
, of limit in milliseconds, should greater than100
ms, default to3600000
.options.prefix
: Optional, Type:String
, redis key namespace, default toLIMIT
.
Limiter.prototype.connect([host, options]) => this
Limiter.prototype.connect(redisClient) => this
Connect to redis. Arguments are the same as thunk-redis's createClient
, or give a thunk-redis instance.
limiter.connect(6379)
Limiter.prototype.get(id, max, duration, max, duration, ...)
Limiter.prototype.get([id, max, duration, max, duration, ...])
Return a promise that guarantee a limiter result. it support more max
and duration
pairs ad limit policy. The first pairs will be used as default. If some trigger limit, then the limiter will apply the next pair policy.
limiter.get('_userIdxxx').then(function (limit) {
console.log(limit)
})
limiter.get('_userIdxxx:POST /files', 100, 60000, 50, 60000).then(function (limit) {
console.log(limit)
})
id
: required, Type:String
, the identifier to limit against (typically a user id)max
: Optional, Type:Number
, max requests withinduration
, default tooptions.max
.duration
: Optional, Type:Number
, of limit in milliseconds, default tooptions.duration
.
Result Object:
limit.remaining
- number of calls left in currentduration
without decreasing currentget
limit.total
-max
valuelimit.duration
- currentduration
in millisecondslimit.reset
- timestamp in milliseconds
Limiter.prototype.remove(id)
limiter.remove('_userIdxxx').then(function (res) {
console.log(err, res)
})