Script Valley
REST API Development: Complete Course from Beginner to Production
Building REST APIs with Express.jsLesson 3.2

Connecting to a Database and Performing CRUD Operations

database connection, MongoDB, Mongoose, environment variables, dotenv, CRUD with database, schema, model

Connecting to a Database and Performing CRUD Operations

A REST API without a database is merely a calculator. Persistent data storage is what makes APIs useful in real applications. This lesson covers connecting Express to MongoDB using Mongoose, defining data models, and implementing all four CRUD operations against real data.

Environment Variables

Never hardcode connection strings or credentials. Use a .env file and the dotenv package:

npm install dotenv mongoose
MONGODB_URI=mongodb://localhost:27017/userapi
PORT=3000

Load them at the top of index.js: require('dotenv').config();

Connecting to MongoDB

const mongoose = require('mongoose');

mongoose.connect(process.env.MONGODB_URI)
  .then(() => console.log('MongoDB connected'))
  .catch((err) => {
    console.error('MongoDB connection error:', err);
    process.exit(1);
  });

Defining a Mongoose Schema and Model

const userSchema = new mongoose.Schema({
  name: { type: String, required: true, trim: true },
  email: { type: String, required: true, unique: true, lowercase: true },
  role: { type: String, enum: ['user', 'admin'], default: 'user' },
  isActive: { type: Boolean, default: true }
}, { timestamps: true });

const User = mongoose.model('User', userSchema);
module.exports = User;

The timestamps: true option automatically adds createdAt and updatedAt fields to every document.

Implementing CRUD Controllers

const getAllUsers = async (req, res) => {
  try {
    const users = await User.find({ isActive: true }).select('-__v');
    res.status(200).json({ success: true, data: users, count: users.length });
  } catch (error) {
    res.status(500).json({ success: false, error: { message: error.message } });
  }
};

const createUser = async (req, res) => {
  try {
    const user = await User.create(req.body);
    res.status(201).json({ success: true, data: user });
  } catch (error) {
    if (error.code === 11000) {
      return res.status(409).json({
        success: false,
        error: { code: 'DUPLICATE_EMAIL', message: 'Email already exists' }
      });
    }
    res.status(500).json({ success: false, error: { message: error.message } });
  }
};

Up next

Middleware in Express: Validation, Logging, and Error Handling

Sign in to track progress