A better project structure with Express and Node.Js

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

  1. /Controllers- This folder would contain all the functions for your APIs.
    Naming of files- xxxxx.controllers.js

  2. /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

  3. /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

  4. /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

  5. /Utils(Optional)- The common functions that you would require multiple times throughout your code
    Naming of files- Normal project file naming scheme

  6. /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

  7. /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

  1. app.js- This file would basically be the entry point of the Express application and should be as minimal as possible

  2. package.json- file which contains all the project npm details, scripts and dependencies.

  3. .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-
LinkedIn- https://www.linkedin.com/in/jugal-bhatt14/
Instagram- https://instagram.com/_jugalbhatt
Github- https://github.com/jugaldb