Middleware
Ingenium middleware uses the same async dispatch model as Koa - await next() in the middle, do work before and after. The signature is a typed ctx plus a zero-argument next:
type IngeniumMiddleware = (ctx: IngeniumContext, next: () => Promise<void>) => unknown | Promise<unknown>
Errors thrown anywhere in the chain bubble up to app.onError. See Errors for the boundary.
A typical middleware
app.use(async (ctx, next) => {
const start = Date.now()
ctx.state.requestId = crypto.randomUUID()
try {
await next()
} finally {
console.log(`${ctx.method} ${ctx.path} -> ${ctx._statusCode} ${Date.now() - start}ms`)
}
})
Mounting middleware on a path prefix
app.use('/admin', adminOnlyMiddleware)
app.use('/admin', adminRouter) // mount middleware OR router
Path-mounted middleware only runs for requests under the prefix. Internally the prefix is stripped before the inner chain runs, so mounted routers see paths relative to their mount point.
Built-in middleware
Ingenium ships with built-ins for the common production needs - all opt-in:
ingenium.json/ingenium.urlencoded- stubs for Express ergonomics; body parsing is lazy.ingenium.static- static files with weak ETags, conditional GET, range requests.ingenium.cors- full CORS with preflight handling.ingenium.sse- Server-Sent Events.ingenium.rateLimit- fixed-window in-memory rate limiting.ingenium.csrf- double-submit cookie or synchronizer-pattern CSRF protection.sessionMiddleware- HMAC-signed cookie sessions with pluggable stores.
Where to next?
- Errors - error classes and the
onErrorboundary. - Body parsing - lazy
ctx.body.*parsers. - CORS - built-in CORS middleware.
- CSRF - built-in CSRF protection.