Files
skills/docs/api-stack/api/api-router/src/route-match/route-match.md
2026-05-29 08:20:56 +01:00

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 parsed RouteOptions block (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 frozen RouteMatch.

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.