A comprehensive, production-ready REST API for a Todo List application built with Node.js, Express, MongoDB, and ECMAScript Modules (ESM). Features include JWT authentication, task management with advanced filtering, email notifications, and user profile management.
Features
- JWT-based Authentication - Secure user authentication with token-based sessions
- Complete Task Management - CRUD operations with advanced filtering and search
- Email Notifications - Task creation confirmations and daily reminders
- User Profile Management - Update name, email, and password
- Advanced Filtering - Filter tasks by completion status, priority, due date, and search terms
- Pagination - Efficient handling of large task lists
- Security Features - Rate limiting, CORS, helmet protection
- Input Validation - Comprehensive request validation using express-validator
- RESTful Design - Clean, intuitive API endpoints
Technology Stack
- Runtime: Node.js with ECMAScript Modules (ESM)
- Framework: Express.js
- Database: MongoDB with Mongoose ODM
- Authentication: JWT (JSON Web Tokens)
- Password Hashing: bcryptjs
- Email Service: Nodemailer
- Validation: express-validator
- Scheduling: node-cron (for daily reminders)
- Security: cors, express-rate-limit
Project Structure
todo-backend-api/
├── server.js # Main server file
├── package.json # Dependencies and scripts
├── .env # Environment variables
├── README.md # API documentation
├── controllers/
│ ├── authController.js # Authentication logic
│ └── taskController.js # Task management logic
├── models/
│ ├── User.js # User data model
│ └── Task.js # Task data model
├── middleware/
│ ├── authMiddleware.js # JWT authentication middleware
│ ├── errorMiddleware.js # Global error handling
│ └── validationMiddleware.js # Input validation rules
├── routes/
│ ├── authRoutes.js # Authentication routes
│ └── taskRoutes.js # Task management routes
├── services/
│ └── emailService.js # Email notification service
└── utils/
├── generateToken.js # JWT token generation
└── responseHandler.js # Standardized API responses
The API will be available at http://todo-list-application.up.railway.app
API Documentation
Base URL
http://todo-list-application.up.railway.app/api
Response Format
All API responses follow this standardized format:
{
"success": true,
"message": "Operation completed successfully",
"data": {
// Response data (when applicable)
}
}
Authentication Endpoints
Register User
Create a new user account.
Endpoint: POST /api/register
Request Body:
{
"name": "John Doe",
"email": "john@example.com",
"password": "password123"
}
Success Response (201):
{
"success": true,
"message": "User registered successfully",
"data": {
"user": {
"id": "60f7b3b3b3b3b3b3b3b3b3b3",
"name": "John Doe",
"email": "john@example.com",
"createdAt": "2023-11-20T10:30:00.000Z"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}
Error Response (400):
{
"success": false,
"message": "User with this email already exists"
}
Login User
Authenticate an existing user.
Endpoint: POST /api/login
Request Body:
{
"email": "john@example.com",
"password": "password123"
}
Success Response (200):
{
"success": true,
"message": "Login successful",
"data": {
"user": {
"id": "60f7b3b3b3b3b3b3b3b3b3b3",
"name": "John Doe",
"email": "john@example.com",
"createdAt": "2023-11-20T10:30:00.000Z"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}
Update Profile
Update user's profile information.
Endpoint: PUT /api/profile
Authentication: Required (Bearer Token)
Request Body:
{
"name": "John Smith",
"email": "johnsmith@example.com",
"password": "newpassword123"
}
Success Response (200):
{
"success": true,
"message": "Profile updated successfully",
"data": {
"user": {
"id": "60f7b3b3b3b3b3b3b3b3b3b3",
"name": "John Smith",
"email": "johnsmith@example.com",
"updatedAt": "2023-11-20T11:00:00.000Z"
}
}
}
Task Management Endpoints
Create Task
Create a new task and send confirmation email.
Endpoint: POST /api/tasks
Authentication: Required (Bearer Token)
Request Body:
{
"title": "Complete project documentation",
"description": "Write comprehensive API documentation for the todo app",
"dueDate": "2023-11-25T15:30:00.000Z",
"priority": "High"
}
Success Response (201):
{
"success": true,
"message": "Task created successfully",
"data": {
"task": {
"_id": "60f7b3b3b3b3b3b3b3b3b3b3",
"title": "Complete project documentation",
"description": "Write comprehensive API documentation for the todo app",
"dueDate": "2023-11-25T15:30:00.000Z",
"priority": "High",
"isCompleted": false,
"userId": "60f7b3b3b3b3b3b3b3b3b3b3",
"createdAt": "2023-11-20T10:30:00.000Z",
"updatedAt": "2023-11-20T10:30:00.000Z"
}
}
}
Get All Tasks
Retrieve tasks with optional filtering, searching, and pagination.
Endpoint: GET /api/tasks
Authentication: Required (Bearer Token)
Query Parameters:
- isCompleted (boolean): Filter by completion status
- priority (string): Filter by priority (Low, Medium, High)
- dueDate (string): Filter by due date (YYYY-MM-DD format)
- search (string): Search in title and description
- page (integer): Page number for pagination (default: 1)
- limit (integer): Number of items per page (default: 10, max: 100)
- sortBy (string): Sort field (default: createdAt)
- sortOrder (string): Sort order - asc or desc (default: desc)
Example Request:
GET /api/tasks?isCompleted=false&priority=High&page=1&limit=5&search=project
Success Response (200):
{
"success": true,
"message": "Tasks retrieved successfully",
"data": {
"tasks": [
{
"_id": "60f7b3b3b3b3b3b3b3b3b3b3",
"title": "Complete project documentation",
"description": "Write comprehensive API documentation",
"dueDate": "2023-11-25T15:30:00.000Z",
"priority": "High",
"isCompleted": false,
"userId": "60f7b3b3b3b3b3b3b3b3b3b3",
"createdAt": "2023-11-20T10:30:00.000Z",
"updatedAt": "2023-11-20T10:30:00.000Z"
}
],
"pagination": {
"currentPage": 1,
"totalPages": 3,
"totalTasks": 15,
"hasNextPage": true,
"hasPrevPage": false,
"limit": 5
}
}
}
Get Single Task
Retrieve a specific task by ID.
Endpoint: GET /api/tasks/:id
Authentication: Required (Bearer Token)
Success Response (200):
{
"success": true,
"message": "Task retrieved successfully",
"data": {
"task": {
"_id": "60f7b3b3b3b3b3b3b3b3b3b3",
"title": "Complete project documentation",
"description": "Write comprehensive API documentation",
"dueDate": "2023-11-25T15:30:00.000Z",
"priority": "High",
"isCompleted": false,
"userId": "60f7b3b3b3b3b3b3b3b3b3b3",
"createdAt": "2023-11-20T10:30:00.000Z",
"updatedAt": "2023-11-20T10:30:00.000Z"
}
}
}
Update Task
Update an existing task.
Endpoint: PUT /api/tasks/:id
Authentication: Required (Bearer Token)
Request Body:
{
"title": "Updated task title",
"description": "Updated description",
"dueDate": "2023-11-26T15:30:00.000Z",
"priority": "Medium",
"isCompleted": true
}
Success Response (200):
{
"success": true,
"message": "Task updated successfully",
"data": {
"task": {
"_id": "60f7b3b3b3b3b3b3b3b3b3b3",
"title": "Updated task title",
"description": "Updated description",
"dueDate": "2023-11-26T15:30:00.000Z",
"priority": "Medium",
"isCompleted": true,
"completedAt": "2023-11-20T12:00:00.000Z",
"userId": "60f7b3b3b3b3b3b3b3b3b3b3",
"createdAt": "2023-11-20T10:30:00.000Z",
"updatedAt": "2023-11-20T12:00:00.000Z"
}
}
}
Delete Task
Delete a specific task.
Endpoint: DELETE /api/tasks/:id
Authentication: Required (Bearer Token)
Success Response (200):
{
"success": true,
"message": "Task deleted successfully"
}
Email Notifications
Task Creation Confirmation
Automatically sent when a new task is created. Contains task details and encouragement message.
Daily Reminders
Automatically sent at 9:00 AM UTC to users who have tasks due the next day. Uses node-cron
for scheduling.
Email Content Includes:
- List of tasks due tomorrow
- Task titles, descriptions, and priorities
- Color-coded priority indicators
- Professional HTML formatting
Authentication
All protected endpoints require a JWT token in the Authorization header:
Authorization: Bearer <your-jwt-token>
Token Structure:
- Expires in 7 days (configurable)
- Contains user ID in payload
- Signed with JWT_SECRET from environment variables
Error Handling
Common Error Responses
Validation Error (400):
{
"success": false,
"message": "Title must be between 1 and 100 characters"
}
Authentication Error (401):
{
"success": false,
"message": "Access denied. No token provided."
}
Not Found Error (404):
{
"success": false,
"message": "Task not found"
}
Server Error (500):
{
"success": false,
"message": "Server error during task creation"
}
Input Validation
User Registration
- name: 2-50 characters, trimmed
- email: Valid email format, lowercase, unique
- password: Minimum 6 characters
Task Creation/Update
- title: 1-100 characters, required, trimmed
- description: Optional, max 500 characters, trimmed
- priority: Must be "Low", "Medium", or "High"
- dueDate: Must be valid ISO 8601 date, future dates only
- isCompleted: Boolean value
Security Features
Rate Limiting
- 100 requests per 15 minutes per IP address
- Applied to all
/api/*
routes
Password Security
- Hashed using bcryptjs with salt rounds of 12
- Never returned in API responses
- Comparison using secure bcrypt.compare()
CORS Protection
- Configurable allowed origins
- Credentials support enabled
Database Schema
User Collection
{
_id: ObjectId,
name: String (required, 2-50 chars),
email: String (required, unique, lowercase),
password: String (required, hashed, min 6 chars),
createdAt: Date,
updatedAt: Date
}
Task Collection
{
_id: ObjectId,
title: String (required, 1-100 chars),
description: String (optional, max 500 chars),
dueDate: Date (optional, future dates only),
priority: String (enum: Low/Medium/High, default: Medium),
isCompleted: Boolean (default: false),
completedAt: Date (set when completed),
userId: ObjectId (required, references User),
createdAt: Date,
updatedAt: Date
}
Database Indexes
-
userId + createdAt
(compound index for efficient task queries) -
userId + isCompleted
(for filtering completed tasks) -
userId + priority
(for priority filtering) -
dueDate
(for reminder email queries)
Deployment
Environment Variables for Production
NODE_ENV=production
PORT=3000
MONGODB_URI=mongodb://your-production-mongodb-uri
JWT_SECRET=your-very-secure-production-jwt-secret
JWT_EXPIRE=7d
# Production Email Service (replace with your SMTP provider)
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USER=your-email@gmail.com
EMAIL_PASS=your-app-specific-password
EMAIL_FROM=noreply@yourdomain.com
# Frontend URL for CORS
FRONTEND_URL=https://your-frontend-domain.com
Top comments (0)