How to Use Middleware with API Routes in Next.js
In Next.js, you can use middleware with API routes by creating reusable functions that process the request and response objects before your main handler. Wrap your API route handler with these middleware functions to add features like authentication or logging using simple function composition.
Syntax
Middleware in Next.js API routes is a function that takes req, res, and next (or returns a promise) to process requests before the main handler. You can create middleware functions and compose them by calling them in sequence or wrapping your handler.
Basic middleware function signature:
function middleware(req, res, next) {
// Do something with req or res
next(); // Call next to continue
}In Next.js API routes, since next() is not built-in, middleware is often implemented as async functions that return a promise and call the next middleware or handler manually.
javascript
async function middleware(req, res, next) { // Your middleware logic here await next(); } export default async function handler(req, res) { await middleware(req, res, async () => { // Main handler logic res.status(200).json({ message: 'Hello from API' }); }); }
Example
This example shows how to create a simple logging middleware that prints the request method and URL, then calls the main API handler.
javascript
async function logger(req, res, next) { console.log(`${req.method} ${req.url}`); await next(); } export default async function handler(req, res) { await logger(req, res, async () => { res.status(200).json({ message: 'Logged your request!' }); }); }
Output
{"message":"Logged your request!"}
Common Pitfalls
- Not calling the next function: Forgetting to call
next()or the next middleware/handler will cause the request to hang. - Middleware order: Middleware must be called in the correct order to work properly.
- Mixing middleware styles: Next.js API routes do not natively support Express-style
next(), so middleware must be async functions that call the next step manually.
javascript
/* Wrong: Missing next call, request hangs */ async function badMiddleware(req, res) { console.log('This will hang because next is not called'); } export default async function handler(req, res) { await badMiddleware(req, res); res.status(200).json({ message: 'This never runs' }); } /* Right: Call next to continue */ async function goodMiddleware(req, res, next) { console.log('Middleware runs'); await next(); } export default async function handler(req, res) { await goodMiddleware(req, res, async () => { res.status(200).json({ message: 'This runs correctly' }); }); }
Quick Reference
- Middleware is an async function that receives
req,res, and anextcallback. - Call
await next()to continue to the next middleware or handler. - Compose multiple middleware by nesting calls or creating a helper to chain them.
- Use middleware for authentication, logging, validation, etc.
Key Takeaways
Middleware in Next.js API routes are async functions that process requests before the main handler.
Always call the next middleware or handler by invoking the provided next callback or promise.
Compose middleware by nesting calls to run multiple functions in order.
Use middleware for common tasks like logging, authentication, and input validation.
Avoid hanging requests by ensuring every middleware calls next or ends the response.