@b9g/router/middleware
Middleware for the @b9g/router package.
Middleware Types
FunctionMiddleware
type FunctionMiddleware = (
request: Request,
context: RouteContext
) => Response | null | void | Promise<Response | null | void>;
Return Response to short-circuit, null or void to continue.
GeneratorMiddleware
type GeneratorMiddleware = (
request: Request,
context: RouteContext
) => AsyncGenerator<Request, Response, Response>;
Use yield to pass control to the next handler.
const timing = async function* (request) {
const start = Date.now();
const response = yield request;
response.headers.set("X-Response-Time", `${Date.now() - start}ms`);
return response;
};
Router.use()
use(middleware: Middleware): void
Registers global middleware.
router.use(loggingMiddleware);
use(path: string, middleware: Middleware): void
Registers path-scoped middleware.
router.use("/api", authMiddleware);
Route.use()
use(middleware: Middleware): Route
Registers route-scoped middleware.
router.route("/api/users/:id")
.use(authMiddleware)
.get(getUser);
Execution Order
LIFO (Last In, First Out) for generator middleware:
Request → Global (before) → Path (before) → Route (before)
↓
Handler
↓
Response ← Global (after) ← Path (after) ← Route (after)
Built-in Middleware
logger(options?: LoggerOptions)
import { logger } from "@b9g/router/middleware";
router.use(logger());
// Custom LogTape category
router.use(logger({ category: ["app", "http"] }));
Logs incoming requests and outgoing responses with timing:
→ GET /
← 200 GET / (3ms)
LoggerOptions
| Option | Type | Default |
|---|---|---|
category |
string[] |
["app", "router"] |
cors(options?: CorsOptions)
import { cors } from "@b9g/router/middleware";
router.use(cors({
origin: "https://example.com",
credentials: true,
}));
CorsOptions
| Option | Type | Default |
|---|---|---|
origin |
string | string[] | (origin: string) => boolean |
"*" |
methods |
string[] |
["GET", "POST", ...] |
allowedHeaders |
string[] |
[] |
exposedHeaders |
string[] |
[] |
credentials |
boolean |
false |
maxAge |
number |
0 |
trailingSlash(mode: "strip" | "add")
import { trailingSlash } from "@b9g/router/middleware";
router.use(trailingSlash("strip")); // /path/ → /path
router.use(trailingSlash("add")); // /path → /path/
Context Augmentation
declare module "@b9g/router" {
interface RouteContext {
user?: User;
}
}
router.use(async (request, context) => {
context.user = await getUser(request);
return null;
});
See Also
- Router - Route definition
- ServiceWorker - Event handling