Back to Tutorials

Integrating MongoDB with Node.js APIs: Complete Guide

Why MongoDB?

MongoDB is a NoSQL database that stores data in flexible, JSON-like documents, making it perfect for modern API development.

Setting Up MongoDB

# Install MongoDB driver
npm install mongodb

# Or use Mongoose ODM
npm install mongoose

Basic MongoDB Connection

const { MongoClient } = require('mongodb');

const uri = 'mongodb://localhost:27017';
const client = new MongoClient(uri);

async function connectDB() {
    try {
        await client.connect();
        console.log('Connected to MongoDB');
        return client.db('myapp');
    } catch (error) {
        console.error('MongoDB connection error:', error);
        throw error;
    }
}

// Use in your routes
app.get('/api/users', async (req, res) => {
    const db = await connectDB();
    const users = await db.collection('users').find({}).toArray();
    res.json(users);
});

Using Mongoose ODM

const mongoose = require('mongoose');

// Connect to MongoDB
mongoose.connect('mongodb://localhost:27017/myapp', {
    useNewUrlParser: true,
    useUnifiedTopology: true
});

// Define Schema
const userSchema = new mongoose.Schema({
    name: { type: String, required: true },
    email: { type: String, required: true, unique: true },
    age: { type: Number, min: 0 },
    createdAt: { type: Date, default: Date.now }
});

// Create Model
const User = mongoose.model('User', userSchema);

// CRUD Operations
app.post('/api/users', async (req, res) => {
    try {
        const user = new User(req.body);
        await user.save();
        res.status(201).json(user);
    } catch (error) {
        res.status(400).json({ error: error.message });
    }
});

app.get('/api/users', async (req, res) => {
    const users = await User.find();
    res.json(users);
});

app.get('/api/users/:id', async (req, res) => {
    const user = await User.findById(req.params.id);
    if (!user) return res.status(404).json({ error: 'User not found' });
    res.json(user);
});

app.put('/api/users/:id', async (req, res) => {
    const user = await User.findByIdAndUpdate(
        req.params.id,
        req.body,
        { new: true, runValidators: true }
    );
    if (!user) return res.status(404).json({ error: 'User not found' });
    res.json(user);
});

app.delete('/api/users/:id', async (req, res) => {
    const user = await User.findByIdAndDelete(req.params.id);
    if (!user) return res.status(404).json({ error: 'User not found' });
    res.json({ message: 'User deleted' });
});

MongoDB Queries

// Find with conditions
const users = await User.find({ age: { $gte: 18 } });

// Find one
const user = await User.findOne({ email: 'user@example.com' });

// Sort and limit
const users = await User.find()
    .sort({ createdAt: -1 })
    .limit(10);

// Aggregation
const stats = await User.aggregate([
    { $group: { _id: null, avgAge: { $avg: "$age" } } }
]);

Best Practices

  • Use connection pooling
  • Index frequently queried fields
  • Validate data with Mongoose schemas
  • Handle connection errors gracefully
  • Use transactions for multi-document operations