Middleware
Middleware functions are functions that have access to the request object (c.req), the response object (via c), and the next function. They can execute code, modify the request/response, and end the request-response cycle.
Why Use Middleware?
Section titled “Why Use Middleware?”Common use cases include:
- Logging: Record details about every incoming request.
- Authentication: Verify if a user is logged in before allowing access.
- Error Handling: Catch errors globally.
- Timing: Measure how long a request takes to process.
Built-in Middleware
Section titled “Built-in Middleware”Hono comes with many built-in middleware. Let’s look at the Logger middleware.
import { Hono } from "hono";import { logger } from "hono/logger";
const app = new Hono();
// Use the logger middleware for all routesapp.use("*", logger());
app.get("/", (c) => c.text("Check your console logs!"));
export default app;When you visit /, you will see a log in your terminal like:
GET / 200 2ms
Custom Middleware
Section titled “Custom Middleware”Creating your own middleware is straightforward.
app.use("*", async (c, next) => { console.log( `[${new Date().toISOString()}] Incoming request: ${c.req.method} ${ c.req.path }` );
await next(); // Pass control to the next handler
console.log("Response sent!");});The next() Function
Section titled “The next() Function”The next() function is crucial. It calls the next middleware or route handler in the stack.
- Code before
await next()runs before the route handler. - Code after
await next()runs after the route handler has finished.
Execution Order
Section titled “Execution Order”Middleware executes in the order it is defined.
app.use(middleware1);app.use(middleware2);app.get("/", handler);Flow: middleware1 (start) -> middleware2 (start) -> handler -> middleware2 (end) -> middleware1 (end).
In our Task Manager, we will use middleware for authentication (later) and logging.
Input Validation with Zod
Section titled “Input Validation with Zod”Validating user input is critical for security and data integrity. Hono has a built-in validator middleware that works great with Zod.
First, install the validator:
bun add zod @hono/zod-validatorThen, use it in your routes:
import { z } from "zod";import { zValidator } from "@hono/zod-validator";
const schema = z.object({ title: z.string().min(3), description: z.string().optional(),});
app.post( "/tasks", zValidator("json", schema, (result, c) => { if (!result.success) { return c.json({ error: "Invalid input", issues: result.error }, 400); } }), (c) => { const data = c.req.valid("json"); return c.json({ message: "Created", task: data }); });