@cedvict/http-guardian-plugin-rate-limit
v0.2.0
Published
Rate limit plugin (concurrency + token bucket) for http-guardian.
Readme
@cedvict/http-guardian-plugin-rate-limit
Rate-limit plugin for http-guardian — combines a per-host concurrency
semaphore and an optional token bucket (req/s). Honors upstream
Retry-After on 429.
Usage
import { rateLimitPlugin } from "@cedvict/http-guardian-plugin-rate-limit";
import { createHttpClient, createApiParserStructured, bearerAuth } from "@cedvict/http-guardian";
const api = createHttpClient({
baseUrl: "https://api.example.com",
auth: bearerAuth(() => token),
parser: createApiParserStructured(),
plugins: [
rateLimitPlugin({
maxConcurrent: 6, // 6 in-flight per host max
tokensPerInterval: 30, // 30 req per interval
intervalMs: 1000, // refill window
honorRetryAfter: true, // pause bucket on 429 Retry-After
}),
],
});Surfacing 429 to the UI — onRateLimited
Set onRateLimited to be notified every time the upstream returns 429. The
event carries the parsed Retry-After (in ms), the raw headers and the host
key so you can show a precise toast ("Trop de requêtes, réessayez dans Ns") or
record a metric without re-parsing at every call-site:
import { rateLimitPlugin } from "@cedvict/http-guardian-plugin-rate-limit";
rateLimitPlugin({
maxConcurrent: 6,
tokensPerInterval: 30,
intervalMs: 1000,
onRateLimited: ({ url, status, retryAfterMs, headers, key, method }) => {
const seconds = retryAfterMs ? Math.ceil(retryAfterMs / 1000) : null;
toast.warn(
seconds
? `Trop de requêtes (${key}). Réessayez dans ${seconds}s.`
: `Trop de requêtes (${key}). Réessayez plus tard.`,
);
metrics.increment("http.rate_limited", { method, host: key });
},
});The callback fires regardless of honorRetryAfter — that flag only controls
whether the bucket pauses; the callback is informational. Errors thrown
from the callback are caught and ignored so a buggy hook never breaks the
request pipeline.
