# Building a Todo App using Express.js + MongoDB

Last time, I wrote about [**Understanding HTTP Requests, Responses, and Methods using Node.js**](https://shubhamsinghbundela.hashnode.dev/understanding-http-requests-responses-and-http-methods-using-node-js).

This time, I took it one step further…

I built a **Todo Application using Express.js and MongoDB**

* * *

### **What I Built**

*   User Signup & Signin
    
*   Create Todo
    
*   Get Todos of logged-in user
    
*   Protected routes using middleware
    
*   MongoDB for database
    

* * *

### Step 1: Setup Express Server

First, I created a basic Express server:

```javascript
const express = require("express");
const app = express();

app.use(express.json());

app.listen(3000, () => {
  console.log("Server is running on port 3000");
});
```

* * *

### **Step 2: Setup MongoDB**

1.  Go to [**https://cloud.mongodb.com/**](https://cloud.mongodb.com/)
    
2.  Create account & login
    
3.  Create a **Cluster**
    
4.  Go to **Database Access**
    
    *   Create username & password
        
5.  Go to **Network Access**
    
    *   Add IP: `0.0.0.0/0` (for development)
        
6.  Click **Connect**
    
7.  Copy connection string
    

Example:

```plaintext
mongodb+srv://username:password@cluster.mongodb.net/dbname
```

* * *

### MongoDB Connection Code

Before connecting MongoDB, first we need to install **mongoose**.

**Step 1: Install Mongoose**

Run this command in your project:

```javascript
npm install mongoose
```

* * *

**Step 2: Connect to MongoDB**

Now write the connection code:

```javascript
const mongoose = require("mongoose");

async function connectDB() {
    try {
        await mongoose.connect("mongodb+srv://<username>:<password>@todo.dtrpx.mongodb.net/todo");
        console.log("MongoDB connected");
    } catch (err) {
        console.error("Connection error:", err);
    }
}

connectDB();
```

Initially, I tried connecting to **MongoDB (cloud)** but faced a DNS issue

**Problem:**

MongoDB connection was failing due to DNS resolution.

**Fix:**

After watching a YouTube video: , I added this:

```javascript
const dns = require("dns");
dns.setServers(["1.1.1.1", "8.8.8.8"]);
```

This fixed the issue and I was able to connect to cloud MongoDB.

* * *

### Step 3: Create Schema using Mongoose

Before writing any backend or frontend logic, I first designed how my data should look.

This step is very important.

**Learning:**  
Always define your **schema first** before building APIs or UI.

Because:

*   It gives clarity on what data you need
    
*   Helps structure your database properly
    
*   Makes backend logic easier to write
    

```javascript
const userSchema = new mongoose.Schema({
    userName: String,
    password: String,
    firstName: String,
    lastName: String
})

const todoSchema = new mongoose.Schema({
    description: String,
    userId: mongoose.Types.ObjectId
})

const userModel = mongoose.model("users", userSchema);
const todoModel = mongoose.model("todos", todoSchema);

module.exports = {
    userModel: userModel,
    todoModel: todoModel
}
```

* * *

### Step 4: Signup Route

Before writing code, let’s understand the goal.

What we want to achieve:

*   Allow a new user to **register**
    
*   Store user details in database
    
*   Prevent duplicate users
    

```javascript
app.post("/signup", async (req, res) => {
  const { userName, password, firstName, lastName } = req.body;

  // checking user exist or not
  const existingUser = await userModel.findOne({
    userName,
    password,
  });

  if (existingUser) {
    return res.status(403).json({
      message: "User already exists",
    });
  }

  // added new user in userModel collection
  const newUser = await userModel.create({
    userName,
    password,
    firstName,
    lastName,
  });

  res.json({
    id: newUser._id,
  });
});
```

* * *

### Step 5: Signin + JWT Token

Before writing code, let’s understand the goal.

What we want to achieve:

*   Verify user credentials
    
*   If valid → allow login
    
*   Generate a **JWT token** for authentication
    

```javascript
app.post("/signin", async (req, res) => {
  const { userName, password } = req.body;

  const userExist = await userModel.findOne({ userName });

  if (!userExist) {
    return res.status(404).json({
      message: "User not found",
    });
  }

  const token = jwt.sign(
    { userId: userExist.id },
    "shubham123"
  );

  res.json({ token });
});
```

* * *

### Step 6: Auth Middleware

This ensures only logged-in users can access routes.

```javascript
function authMiddleware(req, res, next) {
    const token = req.headers.token;

    const decode = jwt.verify(token, "shubham123");

    req.userId = decode.userId;

    next();
}
```

* * *

### Step 7: Create Todo

Before writing the code, let’s understand

**What are we trying to achieve?**

We want:  
1\. Only **logged-in users** should be able to create a todo i.e. Each todo should be linked to the **specific user who created it**

When user tries to create a todo, first **authentication happens** using `authMiddleware`.

*   It verifies the token
    
*   Extracts `userId`
    
*   Attaches it to `req.userId`
    

Then we use this `userId` to link the todo with the logged-in user.

So each todo belongs to a specific user, and later we can fetch user-specific todos.

```javascript
app.post("/todo", authMiddleware, async (req, res) => {
  const newTodo = await todoModel.create({
    description: req.body.description,
    userId: req.userId
  });

  res.json({
    id: newTodo._id
  });
});
```

* * *

### Step 8: Get All Todos

```javascript
app.get("/todos", authMiddleware, async (req, res) => {
  const allTodos = await todoModel.find({
    userId: req.userId
  });

  res.json({ allTodos });
});
```

* * *

### Testing using Postman

I used **Postman** to test APIs.

**Signup**

*   Method: `POST`
    
*   URL: [`http://localhost:3000/signup`](http://localhost:3000/signup)
    
*   Body (JSON):
    

```javascript
{
  "userName": "shubham",
  "password": "1234",
  "firstName": "Shubham",
  "lastName": "Singh"
}
```

* * *

**Signin**

*   Method: `POST`
    
*   URL: `/signin`
    

Copy the **token** from response

* * *

**Create Todo**

*   Method: `POST`
    
*   URL: `/todo`
    
*   Headers:
    

```javascript
token: YOUR_TOKEN
```

*   Body:
    

```javascript
{
  "description": "Learn Express"
}
```

* * *

**Get Todos**

*   Method: `GET`
    
*   URL: `/todos`
    
*   Headers:
    

```javascript
token: YOUR_TOKEN
```

* * *

## Complete Source Code

👉 I’ve uploaded the complete project on GitHub. You can check it here:

**GitHub Repo:**  
[https://github.com/shubhamsinghbundela/Todo-application-using-express/tree/main](https://github.com/shubhamsinghbundela/Todo-application-using-express/tree/main)
