A better project structure with Express and Node.Js
Learning how to structure your folder for other people to understand your code and further work on it easily is a great deal and shows how your coding practices are.
Express is a minimal and flexible Node.Js web application framework that provides a robust set of features for web and mobile applications.
Photo from npmjs.org
To get the most out of your Express applications and make the code readable and understandable for the people out there, it is really necessary to structure your project in a way that anyone can understand which file does what.
Source: LogRocketBlog
Let’s jump in and know more about the project structure itself.
Folders
/Controllers- This folder would contain all the functions for your APIs.
Naming of files- xxxxx.controllers.js/Routes- This folder would contain all the routes that you have created using Express Router and what they do would be exported from a Controller fileNaming of files- xxxxx.routes.js
/Models- This folder would contain all your schema files and and the functions required for the schema would also lie over here.
Naming of files- xxxxx.js/Middleware- This folder would contain all the middleware that you have created, whether it be authentication/some other function.
Naming of files- xxxxx.middleware.js/Utils(Optional)- The common functions that you would require multiple times throughout your code
Naming of files- Normal project file naming scheme/Templates(Optional)- If your code requires you to send certain emails/ HTML code to the client-side, store it in this files
Naming of files- Normal project file naming scheme/Config(Optional)- Configuration files for third party APIs/services like passport/S3,etc
Naming of files- Normal project file naming scheme
Files in the root of your project
app.js- This file would basically be the entry point of the Express application and should be as minimal as possible
package.json- file which contains all the project npm details, scripts and dependencies.
.gitignore- The files you don’t want to push to git
Enough talking, let’s see how the project structure would actually look like with some example files
Models
Models are where all your schema and it’s related functions would lie inside the schema files, what this should do is keep the requests and responses away from itself and not throw an error, this way the errors generated would not affect the schemas and the ones generated by it won’t be confused by the normal APIs
Folder
source: VScode
File example
const mongoose = require(“mongoose”);
const userSchema = new mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
name: String,
email: {
type: String,
lowercase: true,
match: /[a-z0–9!#$%&’*+/=?^_`{|}~-]+(?:\.[a-z0–9!#$%&’*+/=? ^_`{|}~-]+)*@(?:[a-z0–9](?:[a-z0–9-]*[a-z0–9])?\.)+[a-z0–9](?:[a-z0– 9-]*[a-z0–9])?/,
},
password: String,
phone_number: Number,
});
module.exports = mongoose.model(“User”, userSchema);
Controllers
Controllers are the files which define the thing which goes inside the routes, here I will be showing only one controller, if you want to see more of the same file, do visit my GitHub repo.
Folder
source: VScode
File example
const bcrypt = require('bcrypt');
require('dotenv').config()
const jwt = require('jsonwebtoken');
const User = require('../models/user');
const getMe = async (req, res) => {
const userId = req.user.userId
const user = await User.findById(userId)
if(user){
res.status(200).json({
message:"Found",
user,
})
}
else{
res.status(400).json({
message:"Bad request"
})
}}
module.exports = {
getMe,
}
Middleware
Middleware are the functions that you would want your route to go through before using the rest of the defined controllers, it is mostly used for routes which require authentication, uploads, etc.
Folder
Source: VScode
File Example
const jwt = require("jsonwebtoken");
module.exports = function (req, res, next) {
const token = req.header("auth-token");
if (!token) return res.status(400).send("Access Denied!, no token entered");
try {
const verified = jwt.verify(token, process.env.jwtSecret);
req.user = verified;
next();
} catch (err) {
res.status(400).send({
error: "auth failed, check auth- token222"
});
}
};
Routes
The name suggests what this would, it is basically the routes’ definition, kind, endpoint, middleware and controllers to be used
Folder
source: VScode
File Example
const express = require('express');
const checkAuth = require('../middleware/checkAuth.middleware');
const userControllers = require('../controllers/users.controllers');
const router = express.Router();
router.post('/signup',userControllers.userRegister);
router.post('/login',userControllers.userLogin);
router.get('/me', checkAuth, userControllers.getMe);
module.exports = router
app.js
This file contains the gateway to your project, it contains the global project and express settings, it also has the code to connect to your database
File Example-
Link- GitHub Gist
Your Basic project structure should look like:
source: VScode
That is pretty much it, you are now ready to make your own Express project from scratch, if you do fork my repository, make sure to run
npm i
to download all the dependencies.
If you have any questions feel free to reach out to me
Repository link: https://github.com/jugaldb/Node.Js-sample-project-structure
mail- jugalbhatt3@gmail.com
LinkedIn- https://www.linkedin.com/in/jugal-bhatt14/
Instagram- https://instagram.com/_jugalbhatt
Github- https://github.com/jugaldb
Subscribe to my newsletter
Read articles from CodeChef-VIT directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by