HarrisonKamau
2 Feb 2021
•
2 min read
Hello! In this article, we will learn how to avoid long import statements for your Mongoose models. All the snippets in this blog can be found in this repo.
Checkout into the main
branch to see how one would normally import the models using the require
keyword. Looking at the repo, you will notice that it gets tedious to keep track of the definitions of the models within your application. What's more, you need to know how the models are being exported. That is, they can be exported with a name different from the one used in the script definition, which is a common pattern. Or they could be exported as default exports
meaning attempting to require
them as named modules
would definitely raise an error.
In the with-smart-import branch, you will find that all models are registered in the lib/createApp.js
file. lib/createApp
function deals with creating an instance of the Express app, registering all the routes, the middleware, and finally creating a MongoDB connection. As such, it's the best place to register all our models and make them accessible to any route through the Express Request object.
// lib/createApp.js
// import your models
const models = require('../models);
async function createApp() {
const app = express();
// other code here
// register models
app.use(async (req, res, next) => {
req.models = models;
// call the next middleware
await next()
});
}
Then in your route, you can simple do:
// routes/users.js
const express = require('express');
const router = express.Router();
router.get('/users', async (req, res) => {
try {
// grab the User model from the req. object
const { models: { User } } = req;
const users = await User.find().exec();
console.log(users);
} catch(error) {
console.error(`Error here: ${error.message}`)
}
});
And voila!
As an experienced Node.js/JavaScript developer, I've adopted ways of making my code shorter and readable. Normally, you'll find routes being registered individually in the server.js
file. For instance,
app.use('/users', userRoutes)
, then app.use('/clubs', clubRoutes)
and so on and so forth. This to me is a little repetitive. I prefer to classify them as public
and protected
and register them in one line:
// routes/public/index.js
// import all your unprotected routes here, then export them as an array!
module.exports = [
routeOne,
routeTwo,
];
then in your server file, or in lib/createApp.js
you iterate over them and call app.use()
: publicRoutes.forEach((route) => app.use(route))
. See this pattern in use here and here!
Thanks for reading!
HarrisonKamau
Full Stack Engineer | Building SPAs and APIs at scale(~50M users) | React.js, Ruby on Rails, Node.js, Salesforce Marketing Cloud
See other articles by HarrisonKamau
Ground Floor, Verse Building, 18 Brunswick Place, London, N1 6DZ
108 E 16th Street, New York, NY 10003
Join over 111,000 others and get access to exclusive content, job opportunities and more!