🧩 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.