next-api-route-middleware
v1.0.2
Published
Middleware for nextjs api routes
Downloads
14,523
Readme
Introduction
Middleware functions allows us to abstract reusable code that runs before the api handler is invoked. They have access to the req
, res
, and the next
middleware function.
Example uses:
- Add data to the
req
object (without TypeScript complaining!) - Reject wrong request methods
- Capture errors
- Validate body/query data
Getting started
1. Install'r
npm i next-api-route-middleware
2. Create your middleware
Your middleware is a function that accepts req
, res
, and next
. It should call next()
when done, or send a response.
export type NextApiRequestWithUser = NextApiRequest & User;
export const withUser: Middleware<NextApiRequestWithUser> = async (req, res, next) => {
const authCookie = await getUserByCookie();
if (authCookie) {
req.userId = authCookie.userId;
next();
} else {
res.status(401).send({ message: 'Invalid auth cookie.' });
}
};
3. Export the use
function. Include an array of middlewares in the order you want them to execute, along with your handler as the last item in the array.
import { use } from 'next-api-route-middleware';
const handler = async (req: NextApiRequestWithUser, res: NextApiResponse<User>) => {
res.status(200).json({ userId: req.userId });
};
export default use(captureErrors, allowMethods(['GET']), addhUser, handler);
Examples
addUser
You can add data to the req
object, and it will be available in your handler. In this example we get a userId from an http cookie, if the cookie isn't valid we return a 401.
export const addUser: Middleware<NextApiRequestWithUser> = async (req, res, next) => {
const authCookie = await getUserByCookie();
if (authCookie) {
req.userId = authCookie.userId;
next();
} else {
res.status(401).send({ message: 'Invalid auth cookie.' });
}
};
allowMethods
You may find that you need to add args to a middleware. To achieve this we make use of a factory pattern. The allowMethods
function bellow accepts an array of allowed methods, and returns a middleware. We can make use of this factory by calling the function: allowMethods(['GET', 'POST'])
import { Middleware } from 'next-api-route-middleware';
export const allowMethods = (allowedMethods: string[]): Middleware => {
return async function (req, res, next) {
if (allowedMethods.includes(req.method!) || req.method == 'OPTIONS') {
next();
} else {
res.status(405).send({ message: 'Method not allowed.' });
}
};
};
captureErrors
We can also perform actions with inner middleware functions. In this example we wrap the inner middleware functions in a try catch, allowing us to catch any errors that bubble up.
import { Middleware } from 'next-api-route-middleware';
export const captureErrors: Middleware = async (req, res, next) => {
try {
await next();
} catch (error) {
console.error(error);
res.status(500).send({ message: 'Server error!' });
}
};