A real-time messaging backend built with microservices architecture, similar to Telegram or WhatsApp. This project demonstrates a scalable, modular system using Node.js, TypeScript, Docker, and various modern technologies.
Note: This is a portfolio/educational project designed to showcase microservices architecture, modern backend development practices, and system design skills. It is not intended for production use without additional security hardening and optimizations.
The system consists of 5 microservices:
- Auth Service (Port 4001) - User authentication and JWT token management
- User Service (Port 4002) - User profiles and presence management
- Chat Service (Port 4003) - Real-time messaging via WebSocket
- Notification Service (Port 4004) - Push notifications and alerts
- API Gateway (Port 8080) - Central entry point for all requests
- Language: TypeScript
- Framework: Express.js
- Real-time: Socket.io
- Message Queue: RabbitMQ
- Databases:
- PostgreSQL (Auth & User services) with Prisma ORM
- MongoDB (Chat & Notification services)
- Redis (Caching & Presence)
- Validation: Zod
- Logging: Winston
- Containerization: Docker & Docker Compose
- Docker & Docker Compose installed
- Bun 1.0+ (for local development)
- Clone the repository:
git clone https://github.com/BronzonTech-Cloud/missebo-api.git
cd missebo-api- Set up environment variables (REQUIRED):
# Copy the root .env.example to .env (REQUIRED for Docker Compose)
cp .env.example .env
# IMPORTANT: The .env file is REQUIRED - docker-compose.yml will not work without it
# Update the .env file with your own secrets
# For production use, change JWT_SECRET and database passwords!
# Generate a strong JWT secret: openssl rand -base64 32
# For local development, also set up service-specific .env files:
cp auth-service/.env.example auth-service/.env
cp user-service/.env.example user-service/.env
cp chat-service/.env.example chat-service/.env
cp notification-service/.env.example notification-service/.env
cp gateway/.env.example gateway/.envImportant Notes:
- The root
.envfile is REQUIRED - Docker Compose will fail without it - The
.envfile is git-ignored and should never be committed - All secrets must be provided via the
.envfile (no hardcoded defaults) - For production, use strong, randomly generated secrets and consider using Docker secrets or a secrets management service
- Start all services:
docker compose up -d- Initialize the database (run migrations):
docker compose exec auth-service bunx prisma migrate deploy
docker compose exec user-service bunx prisma migrate deploy- Access services:
- API Gateway: http://localhost:8080
- RabbitMQ Management: http://localhost:15672 (admin/admin)
- Auth Service: http://localhost:4001
- User Service: http://localhost:4002
- Chat Service: http://localhost:4003
- Notification Service: http://localhost:4004
- PostgreSQL: localhost:5433 (host port, container uses 5432)
Optional bootstrap (recommended for first run):
./bootstrap.shThis copies .env.example files into each service and installs all dependencies. If you prefer to do things manually, follow the steps below.
- Install dependencies for each service:
./install-deps.shIf you prefer to run them manually:
cd auth-service && bun install
cd ../user-service && bun install
cd ../chat-service && bun install
cd ../shared/auth && bun install
cd ../notification-service && bun install
cd ../gateway && bun install- Start infrastructure services:
docker compose up -d postgres mongodb redis rabbitmq- Set up environment variables (skip if you ran
./bootstrap.sh):
# Copy .env.example to .env in each service directory
cp auth-service/.env.example auth-service/.env
cp user-service/.env.example user-service/.env
cp chat-service/.env.example chat-service/.env
cp notification-service/.env.example notification-service/.env
cp gateway/.env.example gateway/.env
# Update DATABASE_URL and other variables in each .env file if needed
# For local development, you may need to adjust:
# - DATABASE_URL (use localhost instead of service names)
# - REDIS_URL (use localhost instead of service names)
# - RABBITMQ_URL (use localhost instead of service names)
# - MONGODB_URL (use localhost instead of service names)- Run database migrations:
cd auth-service && bunx prisma migrate dev
cd ../user-service && bunx prisma migrate dev- Start each service in separate terminals:
# Terminal 1
cd auth-service && bun run dev
# Terminal 2
cd user-service && bun run dev
# Terminal 3
cd chat-service && bun run dev
# Terminal 4
cd notification-service && bun run dev
# Terminal 5
cd gateway && bun run devPOST /auth/register
Content-Type: application/json
{
"email": "user@example.com",
"password": "securepassword123",
"username": "johndoe",
"displayName": "John Doe"
}POST /auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "securepassword123"
}GET /auth/me
Authorization: Bearer <token>GET /users/:id
Authorization: Bearer <token>PATCH /users/status
Authorization: Bearer <token>
Content-Type: application/json
{
"status": "online" | "offline" | "away"
}GET /messages/:chatId
Authorization: Bearer <token>Connect to: ws://localhost:4003 (or via gateway at ws://localhost:8080/chat)
Events:
message- Send a messagetyping- Broadcast typing indicatorread_receipt- Mark messages as read
GET /notifications
Authorization: Bearer <token>Run tests for all services:
./test.shOr run tests for a single service:
cd <service-name> && bun testCurrent test coverage: 87.33% lines, 83.60% functions
Each service includes unit tests for:
- Auth Service: Registration, login, JWT token generation, user validation (100% coverage)
- User Service: Profile creation, status updates, presence management (100% coverage)
- Chat Service: Message sending, chat creation, read receipts (97.25% coverage)
- Notification Service: Notification creation, event handling (95.59% coverage)
- Gateway: Basic routing and proxy functionality
- Shared Auth: Authentication middleware and error handling (100% coverage)
Run tests with coverage:
bun test --coverageTests are written using Bun's built-in test runner (Jest-compatible API). Example:
import { describe, it, expect } from 'bun:test';
describe('MyService', () => {
it('should do something', () => {
expect(true).toBe(true);
});
});Tests are located alongside the source code:
service-name/
src/
services/
my.service.ts
my.service.test.ts
Check and auto-fix linting issues across all services:
./lint-check.shOr for a single service:
cd <service-name>
bun run lint # Check for linting errors
bun run lint:fix # Auto-fix linting errorsFormat code across all services:
./format.shOr for a single service:
cd <service-name>
bun run format # Format code
bun run format:check # Check formatting without modifying filesmissebo-api/
βββ docker-compose.yml
βββ shared/
β βββ auth/ # Shared authentication package
β βββ auth.middleware.ts # JWT authentication middleware
β βββ types.ts # AuthRequest interface
β βββ AppError.ts # Error class
β βββ index.ts # Exports
β βββ package.json
βββ gateway/
β βββ src/
β βββ Dockerfile
β βββ package.json
βββ auth-service/
β βββ src/
β β βββ index.ts
β β βββ controllers/
β β βββ routes/
β β βββ middleware/ # Re-exports from shared/auth
β β βββ services/
β β βββ types/
β βββ prisma/
β β βββ schema.prisma
β βββ Dockerfile
β βββ package.json
βββ user-service/
β βββ src/
β βββ Dockerfile
β βββ package.json
βββ chat-service/
β βββ src/
β β βββ websocket/
β β βββ events/
β β βββ models/
β βββ Dockerfile
β βββ package.json
βββ notification-service/
β βββ src/
β βββ Dockerfile
β βββ package.json
βββ README.md
Each service requires a .env file. See .env.example in each service directory for required variables.
- β User registration and authentication (JWT)
- β Real-time 1-to-1 messaging
- β Group chat support
- β Read receipts (sent/delivered/read)
- β Typing indicators
- β Online/offline presence
- β Push notifications
- β Message persistence
- β API Gateway with routing
- β Swagger documentation
- β Health check endpoints
- β Docker containerization
- β CI/CD with GitHub Actions
- Services not starting: Check Docker logs with
docker compose logs <service-name> - Database connection errors: Ensure databases are healthy:
docker compose ps - RabbitMQ connection issues: Verify RabbitMQ is running and accessible
- Port conflicts: Check if ports are already in use and modify
docker-compose.yml
This project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Please read our Contributing Guide for details on our code of conduct and the process for submitting pull requests.
This is a portfolio project designed to showcase microservices architecture and development skills. The following are known limitations that would be addressed in a production environment:
Security Enhancements (Production Ready):
- Rate limiting would be implemented using
express-rate-limit - Stronger password requirements would be enforced
- CORS would be configured per environment
- Input sanitization middleware would be added
Production Optimizations:
- Connection pooling would be configured based on expected load
- Circuit breaker pattern would be implemented for resilience
- Enhanced request/response logging for observability
- Performance testing and load testing would be conducted
Architecture Improvements:
- β
Shared auth middleware extracted to common package (
shared/auth) - WebSocket proxy would be implemented in the gateway
- Integration test suite would be added
- API documentation would be generated (OpenAPI/Swagger)
This project is part of my portfolio to demonstrate:
- Microservices architecture design and implementation
- Real-time communication systems (WebSocket)
- Message queue integration (RabbitMQ)
- Multi-database strategies (PostgreSQL, MongoDB, Redis)
- Docker containerization and orchestration
- TypeScript and modern Node.js development
- API Gateway patterns
- Test-driven development
Technologies Showcased:
- TypeScript, Express.js, Socket.io
- Prisma ORM, Mongoose
- RabbitMQ, Redis
- Docker, Docker Compose
- Bun runtime
- JWT authentication
- Microservices patterns