rateLimitRequest counts how often one caller reaches a route and takes over the response once they pass the limit. Wrap any handler with it.

1import { rateLimitRequest, res } from "apiker";
2
3const routes = {
4 "/search": params =>
5 rateLimitRequest("search", params, runSearch, 10, 60 * 60 * 1000)
6};

Arguments

  • prefix — names the bucket. Two routes sharing a prefix share an allowance.
  • params — the handler context, passed straight through.
  • handlerFn — the handler to run while the caller is under the limit.
  • limit — how many requests are allowed. Defaults to 50.
  • timeLapse — the window in milliseconds. Defaults to one hour.
  • onLimitReached — the response to send instead. Defaults to res_429.

A bucket is the prefix combined with the caller's signed IP, so limits are per client rather than global.

Headers

Every response through a rate-limited route carries the caller's remaining allowance:

X-RateLimit-Limit: 10 X-RateLimit-Remaining: 7

Checking without consuming

import { isRateLimitReached } from "apiker"; const { rateLimitReached, requestCount } = await isRateLimitReached("search", 10, 60 * 60 * 1000);

A custom rejection

rateLimitRequest("search", params, runSearch, 10, 60 * 60 * 1000, () => res_429({ message: "Slow down", retryAfter: 3600 }) );
Counters live in the RateLimit object. Leave it out of objects and rate limiting quietly does nothing.