# @suaveplan/api-plugin-rate-limit - Rate-limit plugin for @suaveplan/api. Wraps @suaveplan/rate-limiter as a definePlugin descriptor: per-route + per-tenant configuration, parameterised path matcher, IP whitelist, tenant multiplier applied to numeric limit, Hono middleware factory, 429 + Retry-After + X-RateLimit-* / RateLimit-* headers, OTel counters, RFC 7807 Problem+JSON body. Registers `rateLimitService` in the host ServiceRegistry. Rate-limit plugin for `@suaveplan/api`. Wraps `@suaveplan/rate-limiter` as a `definePlugin` descriptor exposing per-route + per-tenant configuration, parameterised path matching, IP whitelist, applied tenant multiplier, Hono middleware, `X-RateLimit-*` / `RateLimit-*` / `Retry-After` headers, RFC 7807 Problem+JSON 429 body, and OTel counters / histogram. Registers a typed `rateLimitService` slot in the host `ServiceRegistry` so sibling plugins can run manual checks. ## Documentation tree - [error-codes](./src/error-codes/error-codes.md) — Provides the stable, namespaced error-code registry every failure path in `@suaveplan/api-plugin-rate-limit` reports th… - [error-codes](./src/error-codes/error-codes.md) — Provides the stable, namespaced error-code registry every failure path in `@suaveplan/api-plugin-rate-limit` reports th… - [headers](./src/headers/headers.md) — Builds the HTTP response headers and Problem+JSON body the rate-limit middleware writes onto every response (allowed AN… - [headers](./src/headers/headers.md) — Builds the HTTP response headers and Problem+JSON body the rate-limit middleware writes onto every response (allowed AN… - [context-augmentation](./src/middleware/context-augmentation.md) — Augments Hono's `ContextVariableMap` interface so handlers calling `c.get("rateLimit")` get a typed `RateLimitDecision`… - [rate-limit](./src/middleware/rate-limit.md) — Constructs a Hono `MiddlewareHandler` that consults a `RateLimitService` on every request, emits the configured `X-Rate… - [otel](./src/otel/instruments.md) — Builds (and caches) the bundle of OpenTelemetry instruments the rate-limit plugin emits on every check. Operators wirin… - [instruments](./src/otel/instruments.md) — Builds (and caches) the bundle of OpenTelemetry instruments the rate-limit plugin emits on every check. Operators wirin… - [path-matcher](./src/path-matcher/path-matcher.md) — Compiles a Hono-style path pattern string into a regular expression - [path-matcher](./src/path-matcher/path-matcher.md) — Compiles a Hono-style path pattern string into a regular expression - [plugin](./src/plugin/plugin.md) — Factory that returns a typed `PluginDescriptor` for the rate-limit plugin, ready to be passed to `@suaveplan/api`'s plu… - [plugin](./src/plugin/plugin.md) — Factory that returns a typed `PluginDescriptor` for the rate-limit plugin, ready to be passed to `@suaveplan/api`'s plu… - [schemas](./src/schemas/options.md) — Validates the caller-supplied `RateLimitPluginOptions` at the boundary and fills in defaults for every optional field,… - [options](./src/schemas/options.md) — Validates the caller-supplied `RateLimitPluginOptions` at the boundary and fills in defaults for every optional field,… - [rate-limit-service](./src/services/rate-limit-service.md) — Wraps the universal `@suaveplan/rate-limiter` core in the plugin's policy layer: IP whitelist, tenant bypass, tenant mu… - [registry-augmentation](./src/services/registry-augmentation.md) — Augments the `ServiceRegistry` interface owned by `@suaveplan/api-plugin/service-registry` so consumers see the `rateLi… - [types](./src/types/types.md) — Defines the public type surface every other module in the package references — the caller-facing `RateLimitPluginOption… - [types](./src/types/types.md) — Defines the public type surface every other module in the package references — the caller-facing `RateLimitPluginOption… ## Install ```bash bun add @suaveplan/api-plugin-rate-limit ``` ## Quick start ```ts import { createApi } from "@suaveplan/api"; import { createRateLimitPlugin } from "@suaveplan/api-plugin-rate-limit"; 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: ["127.0.0.1"], headerStyle: "both", }) ); ``` Every request flowing through the host Hono app is now rate-limited. Responses carry both legacy `X-RateLimit-Limit` / `X-RateLimit-Remaining` / `X-RateLimit-Reset` and IETF `RateLimit-Limit` / `RateLimit-Remaining` / `RateLimit-Reset` headers. Denied requests return `429` with `Content-Type: application/problem+json` and a `Retry-After` header. ## Manual `service.check(...)` from sibling plugins ```ts import { rateLimitExceeded, type RateLimitService, } from "@suaveplan/api-plugin-rate-limit"; const service = ctx.getService("rateLimitService") as RateLimitService; const decision = await service.check({ ip, tenantId, path: "/api/billing/invoice", method: "POST", }); if (!decision.allowed) throw rateLimitExceeded(decision); ``` ## The 3-way plug-and-play contract This package follows the same contract every `@suaveplan/api-plugin-*` package follows: it owns its boundary Zod schemas (`RateLimitPluginOptionsSchema`), registers a typed slot in the host `ServiceRegistry` (`rateLimitService`), and installs a global Hono middleware via `app.use("*", rateLimit({ service }))` from its canonical 6-step `onInit` lifecycle (resolve services → build storage → construct service → register slot → install middleware → log readiness). ## Modules - [`src/error-codes/error-codes.md`](src/error-codes/error-codes.md) — `RATE_LIMIT_PLUGIN_CODES` registry + `RateLimitPluginError`. - [`src/types/types.md`](src/types/types.md) — public type surface. - [`src/schemas/options.md`](src/schemas/options.md) — Zod schema for caller-supplied options. - [`src/path-matcher/path-matcher.md`](src/path-matcher/path-matcher.md) — Hono-compatible path-pattern compilation + matching. - [`src/headers/headers.md`](src/headers/headers.md) — header bag + Problem+JSON body construction. - [`src/otel/instruments.md`](src/otel/instruments.md) — OpenTelemetry instruments bundle. - [`src/services/rate-limit-service.md`](src/services/rate-limit-service.md) — `RateLimitService` factory. - [`src/services/registry-augmentation.md`](src/services/registry-augmentation.md) — `ServiceRegistry` module augmentation. - [`src/middleware/rate-limit.md`](src/middleware/rate-limit.md) — Hono middleware factory. - [`src/middleware/context-augmentation.md`](src/middleware/context-augmentation.md) — Hono `ContextVariableMap` augmentation. - [`src/plugin/plugin.md`](src/plugin/plugin.md) — `createRateLimitPlugin` factory. ## Status `0.1.0` — initial ship. Surface is final for the 0.1.x line.