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:

1
2
3
mkdir task-api
cd task-api
npm init -y

Step 2: Install Core Dependencies

1
npm install express mongoose dotenv cors helmet

Package purposes:

  • express: Web framework
  • mongoose: MongoDB ODM
  • dotenv: Environment variables
  • cors: Cross-origin resource sharing
  • helmet: Security headers

Step 3: Install Development Dependencies

1
npm install --save-dev nodemon

Update package.json scripts:

1
2
3
4
5
6
{
  "scripts": {
    "start": "node src/server.js",
    "dev": "nodemon src/server.js"
  }
}

Step 4: Create Project Structure

1
2
mkdir -p src/{config,controllers,middleware,models,routes,utils}
touch src/server.js src/app.js .env .gitignore

Your structure should look like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
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:

1
2
3
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:

1
2
3
4
5
6
7
8
9
node_modules/
.env
.env.local
.env.*.local
*.log
.DS_Store
coverage/
dist/
build/

Step 7: Create Basic Express App

src/app.js:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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:

1
2
3
4
5
6
7
8
9
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:

1
npm run dev

You should see:

1
2
🚀 Server running on port 5000
📝 Environment: development

Test the health endpoint:

1
curl http://localhost:5000/api/health

Expected response:

1
2
3
4
5
{
  "status": "success",
  "message": "API is running",
  "timestamp": "2026-01-20T17:30:00.000Z"
}

Step 9: Initialize Git Repository

1
2
3
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:

  1. Set up MongoDB Atlas
  2. Create database connection
  3. Define our first Mongoose model
  4. Implement basic CRUD operations

Common Issues

Port already in use

If port 5000 is occupied:

  1. Change PORT in .env to another number (e.g., 3001)
  2. Or kill the process using port 5000:
1
2
3
4
5
6
# 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