Middleware
Middleware is the main composition mechanism in sevo.
Shape
Middleware receives (ctx, next) and can:
- return a
Responseimmediately - call
next(ctx)and return the downstream response - replace the request before passing it on
import type { ServerMiddleware } from "sevo";
const poweredBy: ServerMiddleware = async (ctx, next) => {
const response = await next(ctx);
response.headers.set("x-powered-by", "sevo");
return response;
};
Registering Middleware
import { serve } from "sevo";
import { NodeRuntimeAdapter } from "sevo/node";
serve({
adapter: new NodeRuntimeAdapter(),
middleware: [poweredBy],
routes: {
"/": () => new Response("ok"),
},
fetch: () => new Response("Not Found", { status: 404 }),
});
Short-Circuiting
Middleware can stop the chain by returning a response directly.
const auth: ServerMiddleware = async (ctx, next) => {
if (!ctx.request.headers.get("authorization")) {
return new Response("Unauthorized", { status: 401 });
}
return next(ctx);
};
Static Files
serveStatic() is implemented as middleware.
import { serve } from "sevo";
import { serveStatic } from "sevo/static";
import { NodeRuntimeAdapter } from "sevo/node";
serve({
adapter: new NodeRuntimeAdapter(),
middleware: [serveStatic({ dir: "./public" })],
fetch: () => new Response("Not Found", { status: 404 }),
});
Request Logging
The optional logger lives in a separate subpath export.
import { serve } from "sevo";
import { log } from "sevo/log";
import { NodeRuntimeAdapter } from "sevo/node";
serve({
adapter: new NodeRuntimeAdapter(),
middleware: [log()],
routes: {
"/": () => new Response("ok"),
},
fetch: () => new Response("Not Found", { status: 404 }),
});
Plugins
ServerPlugin runs during Server construction and can modify server.options
or register process-level behavior.
sevo itself uses plugins internally for:
- request error normalization
- graceful shutdown handling in supported runtimes