Build a RESTful API with Express and MongoDB - Part 1: Project Setup
Series Overview
This is Part 1 of a complete series where we’ll build a production-ready RESTful API from scratch. By the end, you’ll have:
- A fully functional REST API with CRUD operations
- User authentication with JWT
- MongoDB database integration
- Input validation and error handling
- API documentation with Swagger
- Comprehensive testing
- Docker containerization
- Deployment on Render/Railway
What We’re Building
A Task Management API that supports:
- User registration and authentication
- Creating, reading, updating, and deleting tasks
- Filtering and pagination
- Role-based access control
Prerequisites
- Node.js 18+ installed
- MongoDB account (we’ll use MongoDB Atlas free tier)
- Basic JavaScript knowledge
- Code editor (VS Code recommended)
Part 1: Project Setup and Foundation
Let’s get our development environment ready and create the project structure.
Step 1: Initialize Project
Create a new directory and initialize npm:
mkdir task-api
cd task-api
npm init -y
Step 2: Install Core Dependencies
npm install express mongoose dotenv cors helmet
Package purposes:
express: Web frameworkmongoose: MongoDB ODMdotenv: Environment variablescors: Cross-origin resource sharinghelmet: Security headers
Step 3: Install Development Dependencies
npm install --save-dev nodemon
Update package.json scripts:
{
"scripts": {
"start": "node src/server.js",
"dev": "nodemon src/server.js"
}
}
Step 4: Create Project Structure
mkdir -p src/{config,controllers,middleware,models,routes,utils}
touch src/server.js src/app.js .env .gitignore
Your structure should look like:
task-api/
├── src/
│ ├── config/
│ ├── controllers/
│ ├── middleware/
│ ├── models/
│ ├── routes/
│ ├── utils/
│ ├── app.js
│ └── server.js
├── .env
├── .gitignore
└── package.json
Step 5: Configure Environment Variables
Create .env file:
PORT=5000
NODE_ENV=development
MONGODB_URI=mongodb://localhost:27017/taskapi
⚠️ We’ll update MONGODB_URI with Atlas connection string in Part 2.
Step 6: Setup .gitignore
Add to .gitignore:
node_modules/
.env
.env.local
.env.*.local
*.log
.DS_Store
coverage/
dist/
build/
Step 7: Create Basic Express App
src/app.js:
const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const app = express();
// Security middleware
app.use(helmet());
// CORS configuration
app.use(cors({
origin: process.env.NODE_ENV === 'production'
? 'https://yourdomain.com'
: 'http://localhost:3000'
}));
// Body parsing middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Health check endpoint
app.get('/api/health', (req, res) => {
res.status(200).json({
status: 'success',
message: 'API is running',
timestamp: new Date().toISOString()
});
});
// 404 handler
app.use((req, res) => {
res.status(404).json({
status: 'error',
message: 'Route not found'
});
});
// Global error handler
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(err.status || 500).json({
status: 'error',
message: err.message || 'Internal server error'
});
});
module.exports = app;
src/server.js:
require('dotenv').config();
const app = require('./app');
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`🚀 Server running on port ${PORT}`);
console.log(`📝 Environment: ${process.env.NODE_ENV}`);
});
Step 8: Test the Server
Run the development server:
npm run dev
You should see:
🚀 Server running on port 5000
📝 Environment: development
Test the health endpoint:
curl http://localhost:5000/api/health
Expected response:
{
"status": "success",
"message": "API is running",
"timestamp": "2026-01-20T17:30:00.000Z"
}
Step 9: Initialize Git Repository
git init
git add .
git commit -m "Initial project setup"
What We’ve Accomplished
✅ Project initialized with proper structure
✅ Core dependencies installed
✅ Environment configuration ready
✅ Basic Express server running
✅ Security middleware configured
✅ Health check endpoint working
✅ Git repository initialized
Next in Part 2
In the next part, we’ll:
- Set up MongoDB Atlas
- Create database connection
- Define our first Mongoose model
- Implement basic CRUD operations
Common Issues
Port already in use
If port 5000 is occupied:
- Change
PORTin.envto another number (e.g., 3001) - Or kill the process using port 5000:
# macOS/Linux
lsof -ti:5000 | xargs kill -9
# Windows
netstat -ano | findstr :5000
taskkill /PID <PID> /F
Module not found errors
Ensure you ran npm install and all dependencies are in package.json.
Full Code
You can find the complete code for Part 1 on GitHub: [link to be added]
Continue to: Part 2: Database Setup and Models (Coming Soon)
Series Index:
- ✅ Part 1: Project Setup (You are here)
- ⏳ Part 2: Database and Models
- ⏳ Part 3: Authentication
- ⏳ Part 4: Task CRUD Operations
- ⏳ Part 5: Testing
- ⏳ Part 6: Documentation
- ⏳ Part 7: Deployment