Express with MongoDB REST API

Ermias Asmare
10 min readMay 5, 2023

Hey guys

I am starting a series on building REST API with Express js and Mongo DB starting from a crud operation, and multiple image uploads (Cloudinary) to deploying the express server to the digital ocean VPS Ubuntu server.

what should I include??

Topics

  1. Setting up Express and MongoDB
  2. Crud operation using Express and MongoDB
  3. Uploading Multiple Images on Cloudinary using Express Js and MongoDB
  4. User Authentication and Authorization in Express and MongoDB using JWT
  5. Node.js Express test-driven development with Jest
  6. Deploying the Express Server to CPanel
  7. Deploying the Express Server to the VPS Ubuntu server

Topic One: Setting up Express js with MongoDB database

In this topic, we will discuss setting up the Express js app with the MongoDB database

Initial Requirements

  • Code Editor, I prefer Visual Studio Code(VS code)
  • latest Node js version(at the time of writing 18.16.0)
  • git bash, GitHub desktop

Creating a GitHub Repository for the project

GitHub is a code hosting platform for version control and collaboration. It used for storing, tracking, and collaborating on software projects. It makes it easy for developers to share code files and collaborate with fellow developers on open-source projects. GitHub also serves as a social networking site where developers can openly network, collaborate, and pitch their work.

I have created a GitHub repository called REST-API-Express_MongoDB, you can find the source code of this blog @ https://github.com/jrermi12/REST-API-Express_MongoDB.git

Github Repository

After creating your repository on GitHub, clone it using the git bash terminal or just download the GitHub desktop app on your computer and clone it.

cloning a GitHub repository using GitHub desktop

After installing the GitHub desktop app go to the Files on the left top corner as shown in the above image and choose the option clone repository.

Then copy the GitHub repository link from GitHub and go to the GitHub Desktop pop window then choose the URL tab and copy the link to the repository link input box then choose the local directory you want to save the project and finally click on the clone button.

process of cloning a project from GitHub is shown in the next images

copying GitHub repository link
Choosing a directory on the local machine
Cloning the git repository

Once we clone the project to our local machine we can start working on the project, let's open the project using our code editor(VS code).

click on open in Visual Studio code

Once it's opened in visual studio code we can start the project by creating the express app go to the vs code terminal and type npm init

Creating the express app

This output confirms that the package.json file was created successfully, after this, we can start installing the packages we need for this project.

packages required

express, body-parser, cors, dot env, mongoose, uuidv4, express-async-handler-path, nodemon, colors

Installing Packages

Installing packages
npm install express body-parser cors dotenv mongoose colors path nodemon express-async-handler

make sure you install all the packages above if you are following this blog, once the packages are installed you will find node_module and package-lock.json files created.

Folder Structure

The folder structure of the project is as follows, I have created two files index.js and servers.js, and a src folder that contains the config, controller, error, middleware, routes, and utils folders.

Project Folder Structure

we will talk about them one by one while working on a simple crud REST API.

First got to the Index.js file, which is the main entry file for the express app. We import the libraries installed such as express, dot env, cors, and path then initialize the app const app = express() then make the app use the libraries, and finally export the app using module.exports = app

//Importing Libraries
const express = require("express")
require("dotenv").config()
const cors = require("cors")
const path = require("path")

//Initalizing the express app
const app = express();

//Adding Node features
app.use(express.json({limit: "50mb"}));
app.use(express.urlencoded({ limit:"50mb", extended: true}));
app.use(cors());


//Run Node APP
module.exports = app

then we have to listen to the app and set a port where the app run on, I was thinking to make things fancy and create our own debugging print with colors support installing the colors library using npm install colors then going to src-> utils folder and create a development.js file.

development.js

Importing the colors, dot env, and express-async-handler packages and creating a variable ENV that tells the app is in development or production mode.

require("colors")
require("dotenv")
const asyncHandler = require("express-async-handler");
require("dotenv").config({ path: "../../.env"})
const ENV = process.env.EXPRESS_ENV || "PRODUCTION"

so let's create .env file in the folder structure and add the EXPRESS_ENV and set it to “development” and let's go ahead and add PORT=5000

let's go back to development.js and add the colors that are going to be used as text colors, background colors, and underline colors.


function getBgColor(data, bgColor) {
switch (bgColor) {
case "":
return data;
case "bgYellow":
return data.bgYellow;
case "bgBlue":
return data.bgBlue;
case "bgCyan":
return data.bgCyan;
case "bgGreen":
return data.bgGreen;
case "bgRed":
return data.bgRed;
case "bgGrey":
return data.bgGrey;
}
}

function getTextColor(data, textColor) {
switch (textColor) {
case "":
return data;

case "black":
return data.black;
case "blue":
return data.blue;
case "cyan":
return data.cyan;
case "green":
return data.green;
case "red":
return data.red;
case "grey":
return data.grey;
case "yellow":
return data.yellow;
case "magenta":
return data.cyan;
default:
return data.white;
}
}

function getUnderline(data, underline) {
switch (underline) {
case false:
return data;

case true:
return data.underline;
}
}

and Finally, add the function we are going use “printConsole” function, this function is to make our terminal more color-coded based on the scenarios that are output on the terminal

require("colors")
require("dotenv")
const asyncHandler = require("express-async-handler");
require("dotenv").config({ path: "../../.env"})
const ENV = process.env.EXPRESS_ENV || "PRODUCTION"

/*
===============================================================
DEBUG PRINT WITH COLORS SUPPORT
===============================================================
*/
function printConsole(
{ data = "No data" } = {},
{ printLocation = "Print Location not Added" } = {},
{ bgColor = "", textColor = "", underline = false } = {}
) {
if (ENV === "development") {
const finalPrint = getUnderline(
getTextColor(getBgColor(data, bgColor), textColor),
underline
);
console.log(
finalPrint,
"Debugging ON. Please Review".toLocaleUpperCase().red.underline,
printLocation.gray
);
}
}

function getBgColor(data, bgColor) {
switch (bgColor) {
case "":
return data;
case "bgYellow":
return data.bgYellow;
case "bgBlue":
return data.bgBlue;
case "bgCyan":
return data.bgCyan;
case "bgGreen":
return data.bgGreen;
case "bgRed":
return data.bgRed;
case "bgGrey":
return data.bgGrey;
}
}

function getTextColor(data, textColor) {
switch (textColor) {
case "":
return data;

case "black":
return data.black;
case "blue":
return data.blue;
case "cyan":
return data.cyan;
case "green":
return data.green;
case "red":
return data.red;
case "grey":
return data.grey;
case "yellow":
return data.yellow;
case "magenta":
return data.cyan;
default:
return data.white;
}
}

function getUnderline(data, underline) {
switch (underline) {
case false:
return data;

case true:
return data.underline;
}
}

module.exports = {
printConsole,
};

I know this must be the longest and craziest express js with Mongodb setup you ever read, stick with me we are almost done.

Server.js

imported the “dotenv” library to gain access to the .env file, then imported the port number set on it, and finally ran the app on port number 5000 in our case.

//Importing Libraries 
require("dotenv").config();
const app = require(".")

// Importing the development support form utils/development.js
const { printConsole } = require("./src/utils/devlopment");

/*
===============================================================
Importing the port set on the .env, if the port number is not set on .env or the port is being used by another server
running on the local macchine we are asking the app to use 3000 as the port number
===============================================================
*/
const PORT = process.env.PORT || 3000

//Listing to the app and running it on PORT 5000
app.listen(PORT, async () => {
printConsole(
{ data: `Server is live @${PORT}` },
{ printLocation: "index.js:28" },
{
bgColor: "bgGreen",
textColor: "black",
underline: true,
}
)
})

Package.json

Time to run the express app but first let's edit the script section by adding this code “start”: “node server.js” and then open the vs code terminal and run the command npm start

Editing the script section on package.json

let's add the package nodemon, what is nodemon??

Nodemon is a command-line tool that helps with the speedy development of Node. js applications. It monitors your project directory and automatically restarts your node application when it detects any changes. This means that you do not have to stop and restart your applications in order for your changes to take effect.

run the commandnpm i nodemon”

then go back to the package.json file and edit the script section by adding “server”: “nodemon server.js”

Running the express app

!Congratulations our express app is up and running

Last Step

Integrating MongoDB to our express app

to integrate MongoDB into our express app we first have to create a MongoDB database on the MongoDB Atlas or by downloading the MongoDB compass. am gone go with MongoDB Atlas.

go to Mongodb and sign up.

MongoDB atlas Home Screen
MongoDB login Screen

Since I already have databases running on MongoDB atlas, I have to add a new project like that if it’s your first time it will say “New Project” from the get-go.

Creating New project on MongoDB atlas

Then add the Name of the project and click next

Naming project

MongoDB Atlas allows you to add another person to access the project you are creating, well click on “create project” What are you waiting for??

Adding Members to the project

After creating the project you will see an interface like below that allows you to create your database. click on “Build a Database”

Creating database

Then from the options choose the M0 or Free version which gives you a storage size of 512MB, shared RAM, and vCPU, then click on “create”

Choosing database options

Then create a user that can access the database, by inputting a username and password by autogenerating a secure password or adding your weak password “just playing”.

Creating user for the database

Then it will ask you to add entries to your ip access list, it will add your current IP address automatically. then click on “Finish and Close”.

adding entries ip access list

Almost Done, for real this time

You will see an interface like this if you have followed me so far, then click on “connect” next to “cluster0"

Database created

Then a pop window will be displayed, with many options to connect to your application, click on vs code and it will provide you a link to access the database.

Getting the link for the database used for connection to the app

click on the copy icon in section number 3, that's the link to your database. if you carefully see the link, let me just put it down.

mongodb+srv://restapi:<password>@cluster0.r3laqgl.mongodb.net/test

restapi:<password>

you have to replace <password> to the weak password or strong password generated for the user with the username restapi

Getting the link for the database used for connection to the app

we are done creating the database on MongoDB atlas, now we have to add this link to our project let's go back to our project

go to the “.env” file, and add the database link by setting it to “MONOG_DB_URL” as shown below.

make sure you replace the password of the user with the password set to it.

EXPRESS_ENV = development
PORT = 5000
MONGO_REMOTE_URL= mongodb+srv://restapi:<password>@cluster0.r3laqgl.mongodb.net

db_config.js

create a file db_config.js in the “src -> config” directory and create the file db_config.js file, this is where we will connect the database to our project.

after creating the db_config.js file, import the Mongoose library and the MONOG_DB_URL from the “.env” file as shown in the image below.

// Importing the development support form utils/development.js 
const { printConsole } = require("../utils/devlopment");

//Importing the mongoose library used to make the mongodb connection
const mongoose = require("mongoose")

//Importing the mongodb atlas link
const MONGO_DB_URI = process.env.MONO_REMOTE_URL;

Then, create the function that connects the app to the database I called it “connectToDb”. this function has the fancy printConsole function that prints out our connection with the database on the terminal and the async function that connects to the db using the “mongoose.connect” built-in function and the “MONOG_DB_URL” link from .env.


//creating a function called connectToDB that handles the database connectio
const connectToDB = async () => {
try {
printConsole(

{ data: "Connecting to MongoDB ......" },
{ printLocation: "db_config.js:12" },
{ textColor: "yellow" }
);

//creating the mongodb database connection by using MONOG_DB_URI
const DBConnection = await mongoose.connect("mongodb+srv://restapi:D1hlCxGbZITD3vqU@cluster0.r3laqgl.mongodb.net", {
useNewUrlParser: true,
useUnifiedTopology: true,
});

printConsole(

{ data: `Database Connected : ${DBConnection.connection.host}` },
{ printLocation: "db_config.js:24" },
{
textColor: "green",
}
);
} catch (error) {
printConsole(error);

process.exit(1);
}
};

// EXPORTING THE connectToDB function
module.exports = connectToDB;

Finally, import the “connectToDB” function to the index.js file as it is the main entrance of the project, and call the function in order to be executed when the app starts.

index.js

//Importing the connectToDB function to the index.js file as it is the main entry to the project 
const connectToDB = require("./src/config/db_config");

//calling the function or running the function
connectToDB();

let's run the project using “npm run server”

Running the app with a MongoDB connection

Congratulations you can officially setup Express js with MongoDB

You can find the source code for Episode One on Github: Here

Next Episode: CRUD Operations using Express and MongoDB — Here

Thank you

Ermias Asmare

--

--