3.5 KiB
plugin/plugin — createRateLimitPlugin factory
(no submodules)
Purpose
Factory that returns a typed PluginDescriptor for the rate-limit
plugin, ready to be passed to @suaveplan/api's plugin registry.
The descriptor's onInit implements the canonical 6-step lifecycle
shared by every @suaveplan/api-plugin-* package: resolve services,
build storage, construct the service, register the service slot,
install the Hono middleware, log readiness.
The factory Zod-validates the supplied options at the boundary so
invalid input fails fast with RateLimitPluginError(INVALID_INPUT)
carrying the underlying ZodError as cause. Once onInit returns
the plugin is fully wired: every request that flows through the host
Hono app is rate-limited by the configured policy, the
rateLimitService slot is available for sibling plugins, and the
plugin's OTel instruments are emitting against the host meter
provider.
Features
- Zod-validated options at the boundary.
- Six-step canonical
onInitlifecycle. - Defaults to bundled
MemoryStorage; accepts anyRateLimitStoragefor distributed deployments. - Registers
rateLimitServicein the hostServiceRegistry. - Installs the global Hono middleware on
*automatically. onClosereleases the service so subsequent re-inits start fresh.
Usage: Basic
import { createApi } from "@suaveplan/api";
import { createRateLimitPlugin } from "@suaveplan/api-plugin-rate-limit";
const api = createApi();
api.use(
createRateLimitPlugin({
defaultLimit: 100,
defaultWindowMs: 60_000,
})
);
Usage: Advanced
import { createApi } from "@suaveplan/api";
import { createRateLimitPlugin } from "@suaveplan/api-plugin-rate-limit";
import { createMyRedisStorage } from "./my-redis-storage.js";
const api = createApi();
api.use(
createRateLimitPlugin({
defaultLimit: 100,
defaultWindowMs: 60_000,
routes: [
{ path: "/api/login", method: "POST", limit: 5, windowMs: 60_000, id: "login" },
{ path: "/api/users/:id", limit: 30, windowMs: 60_000 },
],
tenants: [
{ tenantId: "enterprise", multiplier: 10 },
{ tenantId: "internal", bypass: true },
],
ipWhitelist: ["10.0.0.0/8"],
headerStyle: "both",
emitRetryAfter: true,
storage: createMyRedisStorage({ url: process.env.REDIS_URL }),
})
);
API Reference
function createRateLimitPlugin(options: RateLimitPluginOptions): PluginDescriptor<RateLimitPluginConfig>— factory.
Implementation Notes
- The 6-step
onInitmirrors the shape every other@suaveplan/api-plugin-*follows so operators reading multiple plugins find a consistent narrative. - The plugin's
nameis"rate-limit"— sibling plugins that depend on it declaredependencies: ["rate-limit"]so the topo sort orders them correctly. onClosenulls the service reference; the storage adapter (if caller-supplied) is the operator's responsibility to dispose.- The plugin DOES install a wildcard middleware (
app.use("*", …)) by default. Consumers who want per-route middleware instead can skip the wildcard mount, resolve the service from the registry, and callrateLimit({ service })themselves — but the default is the safe, secure-by-default position. - The plugin requires the host
appslot. Theclockslot is optional and defaults toDate.now; theloggerslot is also optional and defaults toctx.logger.