2.6 KiB
route-match
(no submodules)
Purpose
The route-match module defines RouteMatch, the shape every concrete
adapter yields after resolving an incoming (method, url) pair against the
router's registry. The host pipeline threads this value through middleware
into the handler — middleware can introspect options to react to per-route
flags (idempotent, rate-limit) without re-parsing.
pluginOfRecord is carried explicitly so the host can stamp telemetry
labels and the rollback journal with the plugin that owns the matched
route, even when middleware is mounted across plugin boundaries.
Features
RouteMatch<Handler>— generic over the handler type so adapters can pin a specific call signature (Hono context vs. in-memory vs. worker proxy).params— parsed path-segment captures, frozen.options— the parsedRouteOptionsblock (post-Zod defaults).createRouteMatch(init)— convenience factory that freezes the result.
Usage: Basic
import { createRouteMatch } from "@suaveplan/api-router/route-match";
import { parseRouteOptions } from "@suaveplan/api-router/route-options";
const match = createRouteMatch({
method: "GET",
path: "/users/:id",
params: { id: "u_42" },
handler: async () => ({ ok: true }),
options: parseRouteOptions({ auth: "users.read" }),
pluginOfRecord: "auth",
});
Usage: Advanced
import type { RouteMatch } from "@suaveplan/api-router/route-match";
type HonoHandler = (ctx: { req: unknown }) => Promise<Response>;
function dispatch(match: RouteMatch<HonoHandler>) {
// match.handler signature is narrowed to HonoHandler
return match.handler({ req: {} });
}
API Reference
RouteMatch<Handler>—{ method, path, params, handler, options, pluginOfRecord }.AnyRouteHandler— type-erased handler signature ((...args) => unknown).createRouteMatch(init)— returns a frozenRouteMatch.
Implementation Notes
Object.freeze is applied in createRouteMatch so middleware that
accidentally tries to mutate the match throws in strict mode — this catches
a class of bugs where downstream middleware reaches into the upstream
match's params and mutates path captures. Adapters that construct
RouteMatch objects directly are expected to apply their own freezing
discipline; the helper is the recommended path.
The handler generic carries through to the consumer so generic dispatch
loops can keep type safety. Erasing to AnyRouteHandler is permitted at
the boundary between adapters (where the host can't know the concrete
signature), but per-adapter code should pin the type.