@jnode/server-ratelimit
v1.0.0
Published
Official rate limit for JNS.
Maintainers
Readme
@jnode/server-ratelimit
Official rate limit package for JNS.
Installation
npm i @jnode/server-ratelimitQuick start
Import
const { createServer, routerConstructors: r, handlerConstructors: h } = require('@jnode/server');
const { routerConstructors: rr } = require('@jnode/server-ratelimit');Start a rate-limited server
const server = createServer(
// apply rate limit: 5 requests per 5 seconds
rr.RateLimit(
// pass: what to do if the request is within limit
h.Text('Welcome! You are not rate-limited.'),
// fail: what to do if the request exceeds limit (default is 429)
h.Text('Too many requests, please try again later.', { statusCode: 429 }),
// limiter configuration
'tb: 5, 5s'
)
);
server.listen(8080);Advanced configuration
const server = createServer(
rr.RateLimit(
h.Text('API accessed.'),
429,
// Configuration: 10 reqs / 1 min, GC every 5 mins,
// auto GC when > 2000 users, force GC every 2 hours
'tb: 10, 1m, 5m, 2000, 2h',
// identify by IP address specifically
'address',
{ disableRetryHeader: false }
)
);
server.listen(8080);How it works?
@jnode/server-ratelimit provides a router that acts as a gatekeeper.
When a request arrives:
- It identifies the client (using the
byparameter, usually by IP address). - It checks the limiter (currently using a Token Bucket algorithm) to see if the client has tokens available.
- If tokens are available, it consumes one and returns the
passrouter/handler. - If no tokens remain, it returns the
failrouter/handler and optionally sets theRetry-Afterheader.
Reference
Router: RateLimit(pass[, fail, limiter, by, options])
passrouter | handler-extended The router or handler to use if the rate limit has not been reached.failrouter | handler-extended The router or handler to use if the rate limit is exceeded. Default:429.limiter<string> | <Function>- If string, format is
type: args. Currently supported type istb(Token Bucket). - If function, signature is
(identity) => true | number. Returnstrueto pass, or anumberrepresenting seconds until retry to fail. - Default:
'tb: 5, 5s'.
- If string, format is
by<string> | <Function> How to identify the client.'auto': Usesctx.identity.idif available, otherwisectx.identity.address.'address': Usesctx.identity.address.- Custom Function:
(env, ctx) => identityString. - Default:
'auto'.
options<Object>disableRetryHeader<boolean> Iftrue, theRetry-Afterheader will not be added to the response on failure. Default:false.
Token Bucket (tb) string format
The limiter string for tb follows this comma-separated argument structure:
'tb: tokens, resetTime, gcTime, autoGC, forceGCTime, gcChunkSize'
tokens: Number of requests allowed per period.resetTime: Time duration before tokens refill (e.g.,'5s','1m','1h').gcTime: How often to run garbage collection for inactive identities. Default:'10m'.autoGC: Max number of tracked identities before triggering GC. Default:1000.forceGCTime: Maximum time to wait before forcing GC regardless ofautoGC. Default:'1h'.gcChunkSize: Number of records to process per GC tick (to prevent blocking the event loop). Default:500.
Time units supported: ms, s, m, h, d. If no unit is provided, it defaults to seconds.
identifyFunctions
- Type: <Object>
A map of built-in identification strategies.
auto:(env, ctx) => ctx.identity.id ?? ctx.identity.addressaddress:(env, ctx) => ctx.identity.address
limiters
- Type: <Object>
A map of available limiter classes.
tb:TokenBucketLimiterclass.
Class: RateLimitRouter
The class used to create the rate limit router.
new RateLimitRouter(pass[, fail, limiter, by, options])
Same arguments as routerConstructors.RateLimit.
rateLimitRouter.route(env, ctx)
Performs the rate limit check and returns either the pass or fail result.
