first commit
This commit is contained in:
64
docs/api-stack/api/api-router-hono/src/adapter/adapter.md
Normal file
64
docs/api-stack/api/api-router-hono/src/adapter/adapter.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# `adapter` — Hono-backed `Router` adapter
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
`HonoRouter` is The concrete `Router` adapter for the API plugin system. It implements every public method of the abstract `Router` contract from `@suaveplan/api-router` (all 7 verb methods, `all`, `use`, `mount`, `match`, `collidesWith`, `chain`) and mirrors every route registration onto a private Hono `Hono` instance. The abstract base owns the match table and collision detection; the Hono instance owns the wire-side dispatch when the host wires a real listener via `getHonoApp()`.
|
||||
|
||||
The adapter exists so a plugin's `RouteSpec[]` can serve traffic through Hono's fast trie router while still being introspectable by the host's collision detector, blue-green slot manager, and OpenAPI emitter — all of which speak the abstract `Router` surface.
|
||||
|
||||
## Features
|
||||
|
||||
- Subclasses `Router`, inheriting `match`/`collidesWith`/`mount` verbatim.
|
||||
- Mirrors registrations onto a private Hono app with a 501 stub handler so the abstract pipeline owns dispatch.
|
||||
- `getHonoApp()` exposes the underlying Hono instance for ops integrations and direct middleware installation.
|
||||
- `createHonoRouter()` factory returns the adapter typed as the abstract `Router` so the `runRouterConformance` harness accepts it unchanged.
|
||||
- Wraps Hono-internal registration throws in `RouterHonoError` (`ROUTER_HONO.HONO_INTERNAL_ERROR`).
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { createHonoRouter } from "@suaveplan/api-router-hono/adapter";
|
||||
|
||||
const router = createHonoRouter({ plugin: "billing" });
|
||||
router.get("/invoices/:id", () => null);
|
||||
const match = router.match("GET", "/invoices/inv_42");
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import { HonoRouter } from "@suaveplan/api-router-hono/adapter";
|
||||
import { Hono } from "hono";
|
||||
|
||||
const router = new HonoRouter({ plugin: "tenants" });
|
||||
router.post("/tenants", { auth: { required: true } }, () => null);
|
||||
router.mount(
|
||||
"/admin",
|
||||
(() => {
|
||||
const child = new HonoRouter({ plugin: "admin" });
|
||||
child.get("/healthz", () => null);
|
||||
return child;
|
||||
})()
|
||||
);
|
||||
|
||||
const app: Hono = router.getHonoApp();
|
||||
app.use("*", async (c, next) => {
|
||||
c.header("x-app", "suaveplan");
|
||||
await next();
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `class HonoRouter extends Router` — public constructor `new HonoRouter({ plugin? })`.
|
||||
- `router.getHonoApp(): Hono` — accessor.
|
||||
- `createHonoRouter(options?): Router` — factory returning the conformance-friendly `Router` view.
|
||||
- Throws `RouterHonoError` with `ROUTER_HONO.HONO_INTERNAL_ERROR` on a Hono-side registration failure.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
`mirror()` normalises trailing slashes and dispatches to the appropriate Hono verb method. `HEAD` is registered via `Hono.on("HEAD", path, ...)` because the runtime Hono surface omits a dedicated `.head()` shorthand. The mirror stub returns a 501 because in-process dispatch goes through the abstract `Router.match()` path — the Hono app is wired only when the host attaches a `fetch` adapter. The match table from the abstract base is the single source of truth for the per-request pipeline (design doc §6).
|
||||
Reference in New Issue
Block a user