Integrating MongoDB database in Webapp
Tags: javascript, webdev, node, mongodb
Published: 2021-11-04 22:21:28

Hi there👋,

In this guide we will be learning how to integrate `MongoDB` in our project using `Mongoose`.
We will be assuming that you have already setup your node.js app
(*or the backend of your app*)

**MongoDB** is an open-source document database and leading `NoSQL` database.
**Mongoose** is an Object Data Modelling(`ODM`) library for `MongoDB` and `Node.js`.

Instead of connecting our node app directly to MongoDB, we will use Mongoose.
![MongoDB managed via Mongoose](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pbqbu4banu389xdv2mp0.PNG)

###🚀 Fasten your seat belt cause we are about to start our journey!
![are you ready](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e58baslhwltqgptgbbwb.png)

For this guide, we will be storing `user` info. in our database.
(*If you're working on complete MERN stack then all of these steps are meant to be perform in the backend of your app.*)

<span>1.</span> Start with installing `Mongoose`.

```javascript
npm install mongoose
```

<span>2.</span> Create a file `userModel.js`.

In this file, we will create a `userSchema`. A `schema` is the structure of the database.

```javascript
import mongoose from "mongoose";

const userSchema = new mongoose.Schema(
  {
    // It atomatically assigns a unique _id, so we don't need to
    // define another id for it.
    firstName: { type: String, required: true },
    lastName: { type: String, required: false },
    email: { type: String, required: true, unique: true },
    pin: { type: Number, required: true },
  },
  {
    timestamps: true,
    // Timestamp of creating a record and last update of record.
  }
);
```

<span>3.</span> Now we will call `mongoose.model()` on our `schema`.

A `mongoose model` is responsible for creating, querying and reading documents from the mongoDB database.

```javascript
const User = mongoose.model("User", userSchema);

export default User;
```

####Your `userModel.js` file should look like this now:


```javascript
import mongoose from "mongoose";

const userSchema = new mongoose.Schema(
  {
    firstName: { type: String, required: true },
    lastName: { type: String, required: false },
    email: { type: String, required: true, unique: true },
    pin: { type: Number, required: true },
  },
  {
    timestamps: true,
  }
);

const User = mongoose.model("User", userSchema);

export default User;
```

<span>4.</span> Now lets create another file named `userRouter.js` to define our API routes for performing **CRUD operations** on it.

```javascript
import express from "express";
import User from "./userModel.js ";

// express.Router() =>  a function to make code Modular, instead of
// creating all routes in server.js we can define multiple files
// to have our routers...
const userRouter = express.Router();

// nature of mongoose operation is async
// so we will define the async functions here.

export default userRouter;
```

<span>5.</span> Before defining our routes in the `userRouter.js`, we will first connect the `mongoose` to the `database`.

For this we need to add a few lines of code in the `server.js` file.

```javascript
import express from "express";
import mongoose from "mongoose";

mongoose.connect(process.env.MONGODB_URL ||
"mongodb://localhost/your_app_name", {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  useCreateIndex: true,
});
```

<span>6.</span> Just two more lines in the `server.js` to connect `server.js` to `userRouter.js`.

```javascript
import userRouter from "./userRouter.js";

app.use("/api/users", userRouter);
```

####The `server.js` file should look like this now:

```javascript
import express from "express";
import dotenv from "dotenv"; // npm install dotenv
import mongoose from "mongoose";
import userRouter from "./router/userRouter.js";

dotenv.config(); // to use .env file content

const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// To connect mongoose to mongoDB database
mongoose.connect(process.env.MONGODB_URL ||
"mongodb://localhost/your_app_name", {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  useCreateIndex: true,
});

// To connect server.js to userRouter.js
app.use("/api/users", userRouter);

// listen command
const port = process.env.PORT || 5000;

app.listen(port, () => {
  console.log(`Serve at http://localhost:${port}`);
});
```

####🌏 So now everything is connected to everything 👩🏻‍💻

![Everything is connected](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vpmbsv61gs3n631ejpxf.PNG)


<span>7.</span> It's time to go back to `userRouter.js` file and define the routes to perform the **CRUD operations**.

```javascript
import express from "express";
import User from "./userModel.js ";

const userRouter = express.Router();

// 1) to read/fetch all users:

userRouter.get(
  "/seed",async (request, response) => {

    // there is no condition defined in find, so it will
    // fetch all users.
    const allUsers = await User.find({});

    response.send({ allUsers });
  };
);


// 2) to create new user:

userRouter.post(
  "/register",async (request, response) => {

    // A request body is data sent by the client to your API.
    const newUser = new User({
      firstName: request.body.firstName,
      lastName: request.body.lastName,
      email: request.body.email,
      pin: request.body.pin,
    });

    const createdUser = await newUser.save();

    response.send({ createdUser });
  };
);


// 3) to update existing user:
// first we need to find that user and then update its info.

userRouter.post(
  "/update",async (request, response) => {
    const editUser = await User.find({ email: request.body.email });


    // When there are no matches find() returns [].
    // So we could not use the condition: if(!editUser){...}

    if (!editUser.length) {
      response.status(400).send({ message: "No User Found" });
    } else {
        editUser.firstName: request.body.firstName,
        editUser.lastName: request.body.lastName,
        editUser.pin: request.body.pin,

        const updatedUser = await editUser.save();

        response.status(201).send({ updatedUser });
    }
  };
);


// 4) to delete a user:
// first we need to find that user and then delete it.

userRouter.delete(
  "/delete",async (request, response) => {
    const deleteUser = await User.find({ email: request.body.email });


    if (!deleteUser.length) {
      response.status(400).send({ message: "No User Found" });
    } else {
        const userDeleted = await deleteUser.deleteOne();

        response.status(201).send({ message: "User removed" });
    }
  };
);

export default userRouter;
```

###🏆 We have successfully integrated Mongoose in our webapp 🔥.

![Mission Passed](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/djre3cqsmdqzrv6ornt1.png)

Now we just need to make a `request` to our server.
For eg. To fetch all users, make a `get` request to:
**"/api/users/seed"**.

There are several other functions with these, such as:
* sort()
* findById()
* findOne()
* findByIdAndUpdate()
* deleteMany() 
* updateMany() and many more.

You could read more on this from [Mongoose Docs](https://mongoosejs.com/docs/queries.html)

![The End](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o8140wkb0mh1u1gag4bb.jpg)