Middleware
Build reusable middleware functions for cross-cutting concerns
Middleware functions allow you to execute code before route handlers, enabling cross-cutting concerns like authentication, logging, and request preprocessing.
Basic Middleware
Create middleware using the middleware helper:
import { server, middleware } from "kitojs";
const logger = middleware((ctx, next) => {
const { method, url } = ctx.req;
console.log(`${method} ${url}`);
next(); // Call next to continue to the next handler
});
const app = server();
app.use(logger); // Apply globally
app.get("/", ({ res }) => {
res.send("Hello");
});Middleware Order
Middleware executes in the order it’s registered:
const first = middleware((ctx, next) => {
console.log("1");
next();
});
const second = middleware((ctx, next) => {
console.log("2");
next();
});
app.use(first);
app.use(second);
// Request will log: 1, 2Global vs Route Middleware
Apply middleware globally or to specific routes:
const app = server();
// Global - runs on all routes
app.use(logger);
// Route-specific
app.get("/admin", [auth, logger], ({ res }) => {
res.send("Admin panel");
});Async Middleware
Use async/await for asynchronous operations:
const dbMiddleware = middleware(async (ctx, next) => {
const { req, db, res } = ctx;
const userId = req.header("user-id");
// Fetch user from database
const user = await db.getUser(userId);
if (!user) {
res.status(404).send("User not found");
return;
}
// Attach user to context (see Context Extensions)
await next();
});Combining Middleware
Stack multiple middleware functions:
const app = server();
app.get(
"/api/admin/users",
[auth, adminCheck, logger, rateLimiter],
({ res }) => {
res.json({ users: [] });
}
); 💡 Tip
Always call next() to continue the middleware chain. Forgetting it will cause requests to hang.
ℹ️ Note
Middleware runs before validation schemas. If you need validated data, use route handlers or context extensions.