Modules
Modules are small, swappable pieces of behavior attached to routes. Each one is a plain interface: bring your own implementation or use the provided defaults.
They can be set at three levels, from lowest to highest precedence:
// 1. Router/app defaults (constructor options or setters)
const app = new Mousse();
app.setDefaultLogger(myLogger)
.setDefaultHTTPErrorHandler(myErrorHandler)
.setDefaultBodyParser(myBodyParser)
.setDefaultResponseSerializer(mySerializer)
.setDefaultRateLimiter(myRateLimiter);
const router = new Router({ logger: routerLogger });
// 2. Route options — override the defaults for this route only
app.get('/special', { logger: specialLogger }, handler);When a router is mounted with use, its routes keep their own options; only the ones left undefined inherit the defaults of the target router.
BodyParser
Turns the raw request body into the value returned by c.body().
interface BodyParser<SchemaDefault> {
parse(raw?: Buffer, contentType?: string, schema?: SchemaDefault): Body | Promise<Body>;
}DefaultBodyParser handles:
| Content type | Result |
|---|---|
application/json |
JSON.parse |
application/x-www-form-urlencoded |
Parsed key/value record |
multipart/form-data |
Record of the non-file fields |
| anything else | The raw Buffer |
ResponseSerializer
Turns the value passed to c.json() (or returned by a handler) into a sendable payload.
interface ResponseSerializer<SchemaDefault> {
serialize(res?: Response, schema?: SchemaDefault): string | Buffer | ArrayBuffer;
// Optional : one serializer per Response schema, built at route registration
compile?(schema: SchemaDefault): (res: any) => string | Buffer | ArrayBuffer;
}DefaultResponseSerializer is JSON.stringify. See compiled serializers.
The schema argument of both interfaces receives the route's schemas option, enabling schema-aware implementations — see Schemas. The defaults ignore it; validation is performed by Mousse itself either way.
RateLimiter
Decides whether a request may go on, before anything of it is analysed. Off until you set one : DefaultRateLimiter is provided. false on a route disables the one inherited from its router. See Rate limiting.
interface RateLimiter {
// Throw or answer through the context to reject the request
check(c): void | Promise<void>;
}Logger
interface Logger {
log(data?: any): void | Promise<void>;
}Available in handlers as c.log(data) (no-op when the route has no logger). Also used to report unhandled route errors when no error handler is set.
Error handlers
interface HTTPErrorHandler {
handle(error: any, c: Context<any>): void | Promise<void>;
}
interface WSErrorHandler {
handle(error: any): void | Promise<void>;
}httpErrorHandler is called when a middleware or handler throws; it may respond through the context. If nothing responded after it ran, Mousse sends a 500. wsErrorHandler covers errors thrown inside WebSocket event listeners.
DefaultHandler
The catch-all executed when no route matched (see Routing):
interface DefaultHandler {
handle: Handler<any, any>;
}Unlike the other modules, a DefaultHandler is not assignable to a single route — "no route matched" is by nature a router-level concern. Set it on the app or a router only, through setDefaultHandler() or the defaultHandler constructor option.
What is not a module
Documentation generation (DocGen, DocSchemaTranslator) is not a module: it is an offline pass over the whole route tree, not a per-request behavior, and follows its own registration rules — see Documentation generation.