Decorator is a neat design pattern which lets you extend the functionality without modifying it. It's usually also a higher order function = function that takes another function as an argument.
I need a way connect to Mongodb
In my NextJS project I use mongodb as a persistence layer, and to be able to do queries I need to :
await connect(config.mongoose.uri, config.mongoose.options)
This turns out to be a repetitive task for any api route or a page.
I could use a middleware
NextJS has a middleware to do that, but I'm not sure that I like using middleware for that purpose.
Middleware gets called for everything, even the _next
routes. And If you don't want to call it for everything, you'd use a matcher
, something like:
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - api (API routes)
* - _next/static (static files)
* - favicon.ico (favicon file)
*/
'/((?!api|_next/static|favicon.ico).*)',
],
}
I prefer decorators instead
Now, a middleware may be perfectly fine for logging, but it looked off to me to use it to connect to the mongo database.
Instead, I created a decorator that connects to the database under the hood. It still is a repetitive task, but I prefer to explicitly call it whenever I need mongodb in the scope.
export function withMongooseSessionApiRoute<T>(
handler: NextApiHandler<T>,
uri: string,
options: ConnectOptions
): NextApiHandler<T> {
return async function nextApiHandler(req: NextApiRequest, res: NextApiResponse) {
await connect(uri, options);
return handler(req, res);
};
}
withMongooseSessionApiRoute
is a function that takes another function (nextjs handler) and mongodb connect options. Inside the withMongooseSessionApiRoute
, a connection to mongo gets done first and nextjs handler call is second.
And for an api route, you'd call like:
export default withMongooseSessionApiRoute(
async function handler(req, res) {
}
);
Small caveat on the current implementation is that cache is not supported for multiple different uris. If you need that implementation, please open a new issue request at https://github.com/eisberg-labs/next-mongoose-session/issues.
You can check out the code and instructions at https://github.com/eisberg-labs/next-mongoose-session.
If you're not sure how to configure mongoose schemas, take a look at my other post!