Microservices Todo Application Development

Ahmad Anis

Ahmad Anis

Todo Microservices Application

A production-ready, full-stack todo application built with microservices architecture using Node.js, TypeScript, React, and MySQL. Features complete Docker containerization and comprehensive test coverage.

πŸ“‹ Table of Contents

πŸ— Architecture Overview

This application follows a microservices architecture with complete containerization support:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Nginx β”‚
β”‚ (Reverse Proxy) β”‚
β”‚ Port: 80 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ β”‚ β”‚
β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β” β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”€β”
β”‚Frontend β”‚ β”‚ User β”‚ β”‚ Todo β”‚
β”‚ (React) β”‚ β”‚ Service β”‚ β”‚Service β”‚
β”‚ :80 β”‚ β”‚ :3001 β”‚ β”‚ :3002 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”¬β”€β”€β”€β”€β”˜
β”‚ β”‚
β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”
β”‚ MySQL β”‚ β”‚ MySQL β”‚
β”‚ userdb β”‚ β”‚ tododb β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Services:

User Service - Handles authentication (register/login) and JWT token generation
Todo Service - Manages CRUD operations for todos with JWT validation
Frontend - React application with Ant Design UI components
Nginx - Reverse proxy for routing and serving static files (Docker mode)

πŸ›  Tech Stack

Backend

Runtime: Node.js (v18+)
Language: TypeScript
Framework: Express.js
Database: MySQL 8.0
ORM: TypeORM
Authentication: JWT (jsonwebtoken)
Validation: Joi
Security: Helmet, CORS, bcrypt
Testing: Jest, Supertest (95% coverage)
Containerization: Docker, Docker Compose

Frontend

Framework: React 18
UI Library: Ant Design (antd)
Routing: React Router v6
HTTP Client: Axios
State Management: React Hooks
Styling: CSS, Ant Design styles
Build: Create React App

DevOps

Containerization: Docker, Docker Compose
Testing: Jest, Supertest
Code Quality: ESLint, Prettier

πŸ“¦ Prerequisites

For Local Development:

Node.js (v16.0.0 or higher)
npm (v7.0.0 or higher)
MySQL (v8.0 or higher)
Git

For Docker Deployment:

Docker (v20.10.0 or higher)
Docker Compose (v2.0.0 or higher)

Verify Installation:

# Local development
node --version # Should output v16.x.x or higher
npm --version # Should output v7.x.x or higher
mysql --version # Should output 8.x.x

# Docker deployment
docker --version
docker-compose --version

πŸ“ Project Structure

todo-microservices/
β”œβ”€β”€ user-service/
β”‚ β”œβ”€β”€ src/
β”‚ β”‚ β”œβ”€β”€ config/ # Database and environment config
β”‚ β”‚ β”œβ”€β”€ controllers/ # Request handlers
β”‚ β”‚ β”œβ”€β”€ middlewares/ # Custom middleware
β”‚ β”‚ β”œβ”€β”€ models/ # Database models
β”‚ β”‚ β”œβ”€β”€ routes/ # API routes
β”‚ β”‚ β”œβ”€β”€ services/ # Business logic
β”‚ β”‚ β”œβ”€β”€ utils/ # Utility functions
β”‚ β”‚ β”œβ”€β”€ validators/ # Input validation schemas
β”‚ β”‚ β”œβ”€β”€ types/ # TypeScript types
β”‚ β”‚ β”œβ”€β”€ app.ts # Express app setup
β”‚ β”‚ └── index.ts # Entry point
β”‚ β”œβ”€β”€ tests/
β”‚ β”‚ β”œβ”€β”€ unit/ # Unit tests
β”‚ β”‚ β”œβ”€β”€ integration/ # Integration tests
β”‚ β”‚ └── setup.ts # Test configuration
β”‚ β”œβ”€β”€ Dockerfile # Docker configuration
β”‚ β”œβ”€β”€ Dockerfile.dev # Development Docker config
β”‚ β”œβ”€β”€ package.json
β”‚ β”œβ”€β”€ tsconfig.json
β”‚ β”œβ”€β”€ jest.config.js
β”‚ β”œβ”€β”€ .env
β”‚ β”œβ”€β”€ .dockerignore
β”‚ └── nodemon.json
β”‚
β”œβ”€β”€ todo-service/
β”‚ β”œβ”€β”€ src/
β”‚ β”‚ └── [Similar structure as user-service]
β”‚ β”œβ”€β”€ tests/
β”‚ β”‚ └── [Similar structure as user-service]
β”‚ β”œβ”€β”€ Dockerfile
β”‚ β”œβ”€β”€ Dockerfile.dev
β”‚ └── [Similar config files]
β”‚
β”œβ”€β”€ frontend/
β”‚ β”œβ”€β”€ public/
β”‚ β”œβ”€β”€ src/
β”‚ β”‚ β”œβ”€β”€ components/ # Reusable components
β”‚ β”‚ β”œβ”€β”€ pages/ # Page components
β”‚ β”‚ β”œβ”€β”€ services/ # API services
β”‚ β”‚ β”œβ”€β”€ utils/ # Utility functions
β”‚ β”‚ β”œβ”€β”€ App.js # Main App component
β”‚ β”‚ └── index.js # Entry point
β”‚ β”œβ”€β”€ Dockerfile
β”‚ β”œβ”€β”€ nginx.conf # Nginx configuration
β”‚ β”œβ”€β”€ package.json
β”‚ └── .env
β”‚
β”œβ”€β”€ docker-compose.yml # Production Docker orchestration
β”œβ”€β”€ docker-compose.dev.yml # Development Docker orchestration
β”œβ”€β”€ Makefile # Convenience commands
β”œβ”€β”€ init-db/
β”‚ └── init.sql # Database initialization
└── README.md # This file

πŸš€ Installation & Setup

Option 1: Quick Start with Docker (Recommended)

# Clone the repository
git clone <repository-url>
cd todo-microservices

# Create environment file
cp .env.docker .env

# Build and run all services
docker-compose up -d

# Application will be available at:
# - Frontend: http://localhost
# - User Service: http://localhost:3001
# - Todo Service: http://localhost:3002

Option 2: Local Development Setup

Step 1: Clone the Repository
git clone <repository-url>
cd todo-microservices
Step 2: Setup MySQL Databases
-- Login to MySQL
mysql -u root -p

-- Create databases
CREATE DATABASE IF NOT EXISTS userdb;
CREATE DATABASE IF NOT EXISTS tododb;

-- Create users
CREATE USER IF NOT EXISTS 'userservice'@'localhost' IDENTIFIED BY 'userpass123';
CREATE USER IF NOT EXISTS 'todoservice'@'localhost' IDENTIFIED BY 'todopass123';

-- Grant privileges
GRANT ALL PRIVILEGES ON userdb.* TO 'userservice'@'localhost';
GRANT ALL PRIVILEGES ON tododb.* TO 'todoservice'@'localhost';
FLUSH PRIVILEGES;

EXIT;
Step 3: Setup and Run Services
# User Service
cd user-service
npm install
cp .env.example .env # Edit with your config
npm run dev

# Todo Service (new terminal)
cd todo-service
npm install
cp .env.example .env # Edit with your config
npm run dev

# Frontend (new terminal)
cd frontend
npm install
cp .env.example .env # Edit with your config
npm start

🐳 Docker Deployment

Production Deployment

# Build and start all services
docker-compose up -d

# View logs
docker-compose logs -f

# Stop all services
docker-compose down

# Rebuild after code changes
docker-compose up -d --build

Development with Hot Reload

# Use development compose file
docker-compose -f docker-compose.dev.yml up

# Services will auto-reload on code changes

Docker Commands Reference

# Build images
docker-compose build

# Start services in background
docker-compose up -d

# View running containers
docker-compose ps

# View logs for specific service
docker-compose logs -f user-service

# Execute command in container
docker-compose exec user-service sh

# Stop and remove everything
docker-compose down -v

# Rebuild specific service
docker-compose up -d --build user-service

Using Makefile

make help        # Show available commands
make build # Build all images
make up # Start all services
make down # Stop all services
make logs # View logs
make test # Run all tests
make clean # Clean up everything

πŸ§ͺ Testing

Test Coverage Summary

User Service: 20 test cases covering authentication
Todo Service: 34 test cases covering CRUD operations
Total Coverage: >90% code coverage

Running Tests

All Tests
# User Service
cd user-service
npm test

# Todo Service
cd todo-service
npm test
Test Categories
# Unit tests only
npm run test:unit

# Integration tests only
npm run test:integration

# Tests with coverage report
npm run test:coverage

# Tests in watch mode
npm run test:watch
Test in Docker
# Run tests in Docker containers
docker-compose exec user-service npm test
docker-compose exec todo-service npm test

# Or use Makefile
make test

Test Database Setup

-- Create test databases
CREATE DATABASE IF NOT EXISTS test_userdb;
CREATE DATABASE IF NOT EXISTS test_tododb;

-- Grant permissions
GRANT ALL PRIVILEGES ON test_userdb.* TO 'root'@'localhost';
GRANT ALL PRIVILEGES ON test_tododb.* TO 'root'@'localhost';
FLUSH PRIVILEGES;

Test Examples

User Registration Test
it('Should register a new user with valid credentials', async () => {
const response = await request(app)
.post('/api/auth/register')
.send({
email: 'test@example.com',
password: 'Test123'
})
.expect(201);

expect(response.body.success).toBe(true);
expect(response.body.data).toHaveProperty('token');
});
Todo CRUD Test
it('Should create a todo for authenticated user', async () => {
const response = await request(app)
.post('/api/todos')
.set('Authorization', `Bearer ${validToken}`)
.send({ content: 'Test todo' })
.expect(201);

expect(response.body.data.content).toBe('Test todo');
});

πŸ“š API Documentation

Base URLs

User Service: http://localhost:3001
Todo Service: http://localhost:3002

Authentication Flow

sequenceDiagram
Client->>User Service: POST /api/auth/login
User Service-->>Client: JWT Token
Client->>Todo Service: GET /api/todos (with JWT)
Todo Service->>Todo Service: Validate JWT
Todo Service-->>Client: Todo List

Endpoints Summary

User Service
Method Endpoint Description Auth Required POST /api/auth/register Register new user No POST /api/auth/login Login user No GET /health Health check No
Todo Service
Method Endpoint Description Auth Required POST /api/todos Create todo Yes GET /api/todos Get all todos Yes GET /api/todos/:id Get single todo Yes PUT /api/todos/:id Update todo Yes DELETE /api/todos/:id Delete todo Yes GET /health Health check No

Postman Collection

Import the complete Postman collection from api-docs/postman-collection.json for easy API testing.

Example Requests

Register User
curl -X POST http://localhost:3001/api/auth/register \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "Test123"}'
Create Todo
curl -X POST http://localhost:3002/api/todos \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{"content": "Complete project"}'

πŸ”§ Environment Variables

User Service (.env)

NODE_ENV=development
PORT=3001
DB_HOST=localhost
DB_PORT=3306
DB_USER=userservice
DB_PASSWORD=userpass123
DB_NAME=userdb
JWT_SECRET=your-super-secret-jwt-key
JWT_EXPIRES_IN=24h
ALLOWED_ORIGINS=http://localhost:3000

Todo Service (.env)

NODE_ENV=development
PORT=3002
DB_HOST=localhost
DB_PORT=3306
DB_USER=todoservice
DB_PASSWORD=todopass123
DB_NAME=tododb
JWT_SECRET=your-super-secret-jwt-key # Must match User Service
ALLOWED_ORIGINS=http://localhost:3000

Frontend (.env)

REACT_APP_USER_SERVICE_URL=http://localhost:3001
REACT_APP_TODO_SERVICE_URL=http://localhost:3002

Docker Environment (.env.docker)

# MySQL
MYSQL_ROOT_PASSWORD=rootpass123

# Services
NODE_ENV=production
JWT_SECRET=your-super-secret-jwt-key
JWT_EXPIRES_IN=24h

# Ports
USER_SERVICE_PORT=3001
TODO_SERVICE_PORT=3002
FRONTEND_PORT=80

πŸ› Troubleshooting

Common Issues and Solutions

Docker Issues
Container won't start:
# Check logs
docker-compose logs service-name

# Rebuild from scratch
docker-compose down -v
docker-compose up --build
Database connection fails:
# Wait for MySQL to be ready
docker-compose exec mysql-db mysqladmin ping -h localhost

# Check database exists
docker-compose exec mysql-db mysql -u root -prootpass123 -e "SHOW DATABASES;"
Testing Issues
Tests failing with "Field 'uuid' doesn't have a default value":
# Ensure test database has correct schema
npm run test:setup

# Or manually sync schema
npm run typeorm schema:sync
JWT token mismatch:
Ensure both services use the same JWT_SECRET
Check token expiration time
Development Issues
CORS errors:
// Update ALLOWED_ORIGINS in .env
ALLOWED_ORIGINS=http://localhost:3000,http://localhost:8080

// Restart services after change
Port already in use:
# Find and kill process
lsof -i :3001 # Mac/Linux
kill -9 <PID>

# Or change port in .env
PORT=3003

Development Guidelines

Write tests for all new features
Maintain >80% code coverage
Follow TypeScript best practices
Use ESLint and Prettier for code formatting
Update documentation for API changes

πŸ‘₯ Authors

Ahmad Anis - Initial work and architecture

πŸ™ Acknowledgments

Built as a technical challenge demonstrating microservices architecture
Implements industry best practices for Node.js and React development
Features comprehensive test coverage and Docker containerization
Follows RESTful API design principles
Implements proper authentication and authorization with JWT

πŸ“Š Project Status

βœ… Core functionality complete
βœ… Docker containerization implemented
βœ… Comprehensive test suite (54+ test cases)
βœ… Production-ready with security best practices
🚧 CI/CD pipeline (optional enhancement)
🚧 Kubernetes deployment (future enhancement)
Happy Coding! πŸš€
For questions or support, please open an issue in the repository.
Like this project

Posted Aug 12, 2025

Developed a microservices-based todo app with Node.js, React, and Docker.