🧩 What is Middleware in Tirne?
In Tirne, middleware is a first‑class, type‑safe function that runs before your route’s handler. It’s not global glue — it’s structured logic.
Think of middleware not as an afterthought, but as an intentional composition unit.
🛠️ Basic Middleware Example
import type { Middleware } from "tirne";
const logger: Middleware = async (req, next) => {
const start = Date.now();
const res = await next();
console.log(`[${req.method}] ${req.url} - ${Date.now() - start}ms`);
return res;
};
Middleware has the signature
(req, next) => Promise<Response>
— and is fully typed.🏗️ Using Middleware (Global)
const server = new Server(routes);
server.use(logger); // applies to all routes
This pattern is useful for logging, auth enforcement, or metrics collection across all endpoints.
🧬 Scoped Middleware (Per Route)
const routes: Route[] = [
{
method: "GET",
path: "/admin",
handler: () => new Response("Welcome, admin"),
middleware: [requireAuth], // only applies here
}
];
You can mix global and route‑scoped middleware. Tirne composes them in order — no surprises.
🧪 Middleware Stack (Execution Flow)
Tirne runs middleware in order, from global to local:
- Global
server.use()
middleware first - Then, route‑specific middleware (if any)
- Finally, the route’s
handler
Middleware must call
await next()
— or the handler won’t run.🔐 Common Middleware Use Cases
- Logging (request time, status)
- Authentication (token, cookies)
- Rate Limiting or CORS
- Header Injection (e.g. security headers)
📎 Summary
Tirne gives you middleware that is:
- 💡 Explicit — always visible, always structured
- ⚙️ Composable — easily reused, fully typed
- 🧪 Predictable — runs in the order you write it
Middleware in Tirne isn’t a “plugin system” — it’s a clean execution model.