Using middleware in Next.js API routes.

Kolby Sisk
Udacity Eng & Data
Published in
2 min readAug 29, 2022

--

TL;DR

Use the next-api-route-middleware package to create composable middleware functions and keep your code clean. 🧽

Middleware

Middleware functions allow us to abstract reusable code that runs before the handler is invoked. They have access to the req, res, and the next middleware function. Unfortunately Next doesn’t include a way to use API middleware (don’t confuse API middleware with Next.js’ edge middleware), so I wrote this small library: next-api-route-middleware.

Example uses:

  • Inspect cookies
  • Add data to the req object
  • Reject unaccepted request methods
  • Capture errors
  • Validate body/query data

Getting started

Install: npm i next-api-route-middleware

Next, create a middleware function. A middleware function accepts req, res, and next. It should call next() when done, or send a response.

Last step is to utilize the use function to compose your middleware

export default use(captureErrors, handler);

Example middleware functions

Add to req middleware

Let’s create a middleware function that adds a new property to the req. This function will parse an HTTP cookie to get the user data, and then either add the user data to the req, or return a 401 error if there isn’t a valid cookie.

Nice, now our handler has access to req.user. Notice that the middleware calls next() when it’s done, unless there is an error in which case it sends a response. The library code checks for res.headersSent and will stop executing the middleware if it detects a response has been sent.

Accepted methods middleware

This middleware simply checks the request method and returns an error if it’s not an expected method for the handler. Because allowMethods needs to accept an argument (an array of allowed methods), we make use of a factory pattern. Calling allowMethods will return a middleware with the allowed methods array injected.

Capture errors

It’s important to capture any errors that could occur in your handler, and return the appropriate 500 status code. This is also a good pattern for utilizing error tracking tools like Sentry.

Because our middleware injects the next middleware (and transversely all inner middlewares), we can wrap a try…catch around all the next middlewares and catch any errors that bubble up.

Conclusion

Middleware is an awesome solution for abstracting composable functions and keeping our code squeaky clean. I hope others find the next-api-route-middleware package useful. If you do find it useful, or have ideas to improve it, I’d love to hear your feedback!

If you want to keep up with the latest in webdev make sure to follow me here and on Twitter @Kolbysisk. 🙏

--

--

Builder of software with a passion for learning. I specialize in web development and user experience design. www.kolbysisk.com