first commit
This commit is contained in:
74
docs/api-stack/api/api-router/src/route-match/route-match.md
Normal file
74
docs/api-stack/api/api-router/src/route-match/route-match.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# `route-match`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## 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
|
||||
|
||||
```ts
|
||||
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
|
||||
|
||||
```ts
|
||||
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.
|
||||
Reference in New Issue
Block a user