Dev Dissection — Week 2: Connecting Your API to MongoDB
Welcome back to Dev Dissection!
Last week, we built a simple TODO API using Node.js, Express, and TypeScript. This week, we’re going to persist our data by integrating a real database — MongoDB.
By the end of this lesson, your TODOs won’t vanish when the server restarts.
Prerequisites
Make sure you have:
- MongoDB installed locally or a free MongoDB Atlas cluster set up
- MongoDB compass or any tool that helps navigating DB
- The Week 1 TODO API working
- A .env file ready for storing secrets
- Basic familiarity with command line and JavaScript
SQL vs NoSQL (Quick Breakdown)
SQL (Relational):
Structured tables (like Excel sheets) with rows and columns. You define a schema up front.
Examples: MySQL, PostgreSQL.
NoSQL (Non-relational):
Flexible, nested documents (JSON-like). You can have varying data structures.
Example: MongoDB.
| Feature | SQL | NoSQL (MongoDB) |
| Schema | Strict, pre-defined | Flexible, dynamic |
| Structure | Tables, rows | Collections, documents |
| Query Lang | SQL | BSON-based (JSON-like) |
MongoDB is great when data structures evolve rapidly — perfect for early-stage projects and agile development.
Let’s Set Up MongoDB with Mongoose
Step 1: Install dependencies
npm install mongoose dotenv
npm install -D @types/mongoose
Step 2: Create a .env file
In your project root, add:
| MONGO_URI=mongodb://localhost:27017/todos-dev |
Step 3: Update your src/index.ts
import express, { Request, Response } from 'express';
import cors from 'cors';
import mongoose from 'mongoose';
import dotenv from 'dotenv';
dotenv.config();
const app = express();
const PORT = 4000;
app.use(cors());
app.use(express.json());
// Connect to MongoDB
mongoose
.connect(process.env.MONGO_URI!)
.then(() => console.log('Connected to MongoDB'))
.catch((err) => console.error('MongoDB connection error:', err));
// Define interfaces for request bodies
interface CreateTodoBody {
task?: string;
}
interface UpdateTodoBody {
task?: string;
completed?: boolean;
}
// Define a Mongoose schema and model
const todoSchema = new mongoose.Schema(
{
task: { type: String, required: true },
completed: { type: Boolean, default: false },
},
{ timestamps: true },
);
const Todo = mongoose.model('Todo', todoSchema);
// CRUD Routes
// Create
app.post(
'/todos',
async (req: Request<{}, {}, CreateTodoBody>, res: Response) => {
try {
const task = req.body.task;
if (!task) {
res.status(400).json({ error: 'Task is required' });
return;
}
const newTodo = await Todo.create({ task: task });
res.status(201).json(newTodo);
} catch (err) {
res.status(400).json({ error: 'Failed to create TODO' });
}
},
);
// Read
app.get('/todos', async (_req: Request, res: Response) => {
const todos = await Todo.find();
res.status(200).json(todos);
});
// Update
app.put(
'/todos/:id',
async (req: Request<{ id: string }, {}, UpdateTodoBody>, res: Response) => {
try {
if (!mongoose.Types.ObjectId.isValid(req.params.id)) {
res.status(400).json({ error: 'Invalid ID format' });
return;
}
if (!req.body) {
res.status(400).json({ error: 'Please send correct inputs' });
return;
}
const { task, completed } = req.body;
if (!task || completed) {
res.status(400).send('Please send correct inputs');
return;
}
const updated = await Todo.findByIdAndUpdate(req.params.id, req.body, {
new: true,
});
if (!updated) {
res.status(404).json({ error: 'Not found' });
return;
}
res.json(updated);
} catch (err) {
console.log(err);
res.status(400).json({ error: 'Failed to update TODO' });
}
},
);
// Delete
app.delete(
'/todos/:id',
async (req: Request<{ id: string }>, res: Response) => {
if (!mongoose.Types.ObjectId.isValid(req.params.id)) {
res.status(400).json({ error: 'Invalid ID format' });
return;
}
const deleted = await Todo.findByIdAndDelete(req.params.id);
if (!deleted) {
res.status(404).json({ error: 'Not found' });
return;
}
res.status(204).send('Todo was completed successfully');
},
);
app.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}`);
});
Try it Out
Start your server:
npm run dev
Test endpoints using:
- Hoppscotch
- Postman
- Frontend (coming soon!)
What You Learned
This week, you:
- Learned SQL vs NoSQL basics
- Set up and configured MongoDB
- Used Mongoose to define models
- Built a persistent TODO API
Coming Up: React Frontend
In Week 3, we’ll:
- Build a React UI to interact with your API
- Use Axios or fetch to get data
- Show and update TODOs live

Hey, I’m Bahroze, I specialize in helping startups build and launch MVPs, making sure you get your customers/clients onboarded fast. My approach mixes tech expertise with startup knowledge, making it easy to work with any tech stack. When I’m not coding, you’ll find me traveling, gaming, or listening to podcasts.
