Understanding the Folder Structure
Explore the essential components of a Node.js backend folder structure and understand how to organize middleware, models, routes, and configuration files. This lesson guides you in creating scalable architecture that supports separation of concerns and maintainability for your applications.
We'll cover the following...
The importance of folder structure
The importance of creating a good architecture in a Node.js project can’t be overemphasized. This will determine if the project can scale and stand the test of time as the application begins to grow and more features need to be added. Some of the reasons for having a good folder structure or architecture in a Node.js project include the following:
- Separation of concern. This helps to reduce duplication of work, i.e., the codebase will become maintainable.
- Easy implementation of business logic.
- Programming practices like “don’t repeat yourself” (DRY), dependency injection, singularity of purpose, etc., can be implemented in the project.
The structure of our Node.js application
The code below shows the structure of the backend folder in our course management application using Node.js. Next, we take a closer look at the function each folder and file performs.
/* This middleware function helps to handle errors that are thrown during asynchronous code execution in Express */
The middleware folder
In a Node.js application, a middleware folder has access to the req and res objects, and the next() function. There are three types of middleware:
-
The “Not Found” middleware.
-
The “Server Error” middleware.
-
The “Token Verification” middleware.
The three types of middleware stated above are contained inside our middleware folder. They help handle scenarios where an API route can’t be found, scenarios where there’s a server error, and scenarios where a token needs to be verified and checked for expiration.
The models folder
This is the folder where we define all of our schemas. A schema helps define our database’s shape in the MongoDB atlas dashboard. In the case of our course management application, we’ll use two different schemas:
-
Course schema: This schema helps determine the shape of the courses we store in the MongoDB database.
-
User schema: This schema helps determine the shape of the data of the users that register and log in to our application in the MongoDB database.
The node_modules folder
This is an automatically generated folder in our Node.js application. It helps to save any external packages or libraries we install using npm, which allows us to import them within our application without referencing a particular path.
The routes folder
The routes in our application will be configured using the Express framework. Routes are used to define how the endpoints in our application respond to clients’ requests. They are defined by using specific HTTP request methods like GET, POST, PUT, and DELETE. In our course management application, we’ll create two routes called the userRoutes.js and courseRoutes.js inside the routes folder.
The utils folder
The utils folder serves as a form of utility to create the logic for our helper functions. In our project, our utils folder will contain the logic for setting up our JSON Web Token.
The .env file
This is an environmental variables file. It’s a text file that contains credentials we want to keep secret and secure. Because of the sensitivity of this file, it’s best practice to exclude it from the files and folders that get pushed to a version control system like Git. The .env file in our application will contain our JSON Web Token and our MongoDB credentials.
The .gitIgnore file
This is a text file that tells Git which files or folders to ignore in a project. We’ll include our node_modules folder and .env file in the .gitIgnore file during the implementation of our project.
The package-lock.json file
This is an automatically generated file required for situations where modifications are made to either the node_modules tree or the package.json file.
The package.json file
This file is the engine room of our Node.js application. It helps to store and manage the metadata in a Node.js project. It also helps handle the installed dependency packages and metadata details, such as the project description, the project version, the license, and the project name. Below is what the package.json file in our application will look like:
{
"name": "backend",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "nodemon server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"bcryptjs": "^2.4.3",
"cors": "^2.8.5",
"dotenv": "^10.0.0",
"express": "^4.17.1",
"express-async-handler": "^1.1.4",
"jsonwebtoken": "^8.5.1",
"mongoose": "^5.13.2",
"mongoose-unique-validator": "^2.0.3",
"morgan": "^1.10.0",
"nodemon": "^2.0.12"
}
}
The procfile file
TThis is a text file included in the root directory. It’s created while deploying the backend of our Node.js application to Heroku and functions as a system used to declare the commands executed by the application on startup.
The serve.js file
This file serves as the entry point of our Node.js application. All the functionalities in our Node.js project are implemented and put together. It is usually listed in the package.json file within the start scripts, as seen below:
"scripts": {
"start": "nodemon server.js"
}
It’s executed by running specific commands in the terminal.