Middleware
Middleware in Yelix
Section titled “Middleware in Yelix”Yelix provides enhanced middleware handling with named middleware support, execution time tracking, and better debugging capabilities.
Basic Middleware
Section titled “Basic Middleware”You can use middleware just like in Hono:
import { YelixHono } from "@yelix/hono";
const app = new YelixHono();
// Global middlewareapp.use("*", async (c, next) => { console.log("Global middleware executed"); await next();});
// Path-specific middlewareapp.use("/api/*", async (c, next) => { // Only applies to /api/* routes await next();});Named Middleware
Section titled “Named Middleware”Named middleware provides better tracking, logging, and debugging. Use the namedMiddleware function to create middleware with a name:
import { YelixHono, namedMiddleware } from "@yelix/hono";
const app = new YelixHono();
// Create a named middlewareconst loggerMiddleware = namedMiddleware("logger", async (c, next) => { app.yelixLog(c, "Logger middleware executed"); await next();});
// Use the named middlewareapp.use(loggerMiddleware);Benefits of Named Middleware
Section titled “Benefits of Named Middleware”- Better tracking: Named middleware appears in the dashboard with its name
- Execution time: Track how long each middleware takes to execute
- Logging: Logs are associated with the middleware name
- Debugging: Easier to identify which middleware is causing issues
Using Named Middleware with Routes
Section titled “Using Named Middleware with Routes”import { YelixHono, namedMiddleware } from "@yelix/hono";
const app = new YelixHono();
// Create named middlewareconst authMiddleware = namedMiddleware("auth", async (c, next) => { const token = c.req.header("Authorization"); if (!token) { return c.json({ error: "Unauthorized" }, 401); } app.yelixLog(c, "Authentication successful"); await next();});
const rateLimitMiddleware = namedMiddleware("rate-limit", async (c, next) => { // Rate limiting logic app.yelixLog(c, "Rate limit check passed"); await next();});
// Apply to specific routesapp.get( "/api/protected", authMiddleware, rateLimitMiddleware, (c) => { return c.json({ message: "Protected resource" }); });Named Middleware with Metadata
Section titled “Named Middleware with Metadata”You can attach metadata to named middleware for additional context:
import { YelixHono, namedMiddleware } from "@yelix/hono";
const app = new YelixHono();
const customMiddleware = namedMiddleware( "custom-middleware", async (c, next) => { await next(); }, { version: "1.0.0", description: "Custom middleware for API", // Any custom metadata });
app.use(customMiddleware);Logging in Middleware
Section titled “Logging in Middleware”Use yelixLog() to log messages from your middleware:
import { YelixHono, namedMiddleware } from "@yelix/hono";
const app = new YelixHono();
const loggerMiddleware = namedMiddleware("request-logger", async (c, next) => { const start = Date.now();
app.yelixLog(c, "Request started", { method: c.req.method, path: c.req.path, });
await next();
const duration = Date.now() - start; app.yelixLog(c, "Request completed", { duration: `${duration}ms`, status: c.res.status, });});
app.use(loggerMiddleware);Complete Example
Section titled “Complete Example”import { YelixHono, namedMiddleware } from "@yelix/hono";
const app = new YelixHono();
// Create multiple named middlewareconst corsMiddleware = namedMiddleware("cors", async (c, next) => { c.header("Access-Control-Allow-Origin", "*"); c.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); app.yelixLog(c, "CORS headers set"); await next();});
const timingMiddleware = namedMiddleware("timing", async (c, next) => { const start = Date.now(); await next(); const duration = Date.now() - start; app.yelixLog(c, `Request took ${duration}ms`);});
const authMiddleware = namedMiddleware("auth", async (c, next) => { const apiKey = c.req.header("X-API-Key"); if (apiKey !== "secret-key") { return c.json({ error: "Invalid API key" }, 401); } app.yelixLog(c, "Authentication successful"); await next();});
// Apply middlewareapp.use(corsMiddleware);app.use(timingMiddleware);
// Apply auth only to API routesapp.use("/api/*", authMiddleware);
// Routesapp.get("/", (c) => { return c.json({ message: "Hello!" });});
app.get("/api/data", (c) => { return c.json({ data: "Protected data" });});
Deno.serve({ port: 8000 }, app.fetch);Middleware Execution Order
Section titled “Middleware Execution Order”Middleware executes in the order they are added:
app.use(middleware1); // Executes firstapp.use(middleware2); // Executes secondapp.use(middleware3); // Executes third
app.get("/route", handler); // Handler executes lastWhen using multiple middleware on a route:
app.get( "/route", middleware1, // Executes first middleware2, // Executes second middleware3, // Executes third handler // Handler executes last);Best Practices
Section titled “Best Practices”- Use named middleware for better debugging and monitoring
- Log important events using
yelixLog()for dashboard visibility - Keep middleware focused - each middleware should do one thing
- Order matters - place authentication middleware before route handlers
- Use path-specific middleware when possible to avoid unnecessary execution