A scalable, event-driven microservices architecture for processing e-commerce orders with reliable message queuing, email notifications, and inventory management.
- Overview
- Architecture
- Features
- Tech Stack
- Project Structure
- Prerequisites
- Getting Started
- Configuration
- API Endpoints
- How It Works
- Development
- Contributing
The Order Processing System is a distributed microservices application that handles order creation, processing, and notification workflows. It implements the Outbox Pattern for reliable message publishing and uses AWS SQS for asynchronous order processing, ensuring data consistency and fault tolerance.
- ✅ Microservices Architecture - Two independent services for order management and processing
- ✅ Event-Driven Design - Asynchronous order processing using message queues
- ✅ Reliable Messaging - Outbox pattern ensures no message loss
- ✅ Inventory Management - Real-time stock validation and updates
- ✅ Email Notifications - Automated order confirmation emails
- ✅ JWT Authentication - Secure user authentication and authorization
- ✅ Transaction Safety - MongoDB transactions for data consistency
The system consists of two microservices:
┌─────────────────┐ ┌──────────────┐ ┌─────────────────────┐
│ Order Service │────────▶│ AWS SQS │────────▶│ Order Processing │
│ (Producer) │ │ (Queue) │ │ Service (Consumer) │
└─────────────────┘ └──────────────┘ └─────────────────────┘
│ │
│ │
▼ ▼
┌──────────┐ ┌──────────┐
│ MongoDB │ │ MongoDB │
│ (Orders) │ │ (Orders) │
└──────────┘ └──────────┘
Order Service (order-service/)
- User authentication and authorization
- Order creation and validation
- Inventory management
- Outbox pattern implementation
- Message publishing to SQS queue
Order Processing Service (order-processing-service/)
- Consumes messages from SQS queue
- Processes orders asynchronously
- Sends order confirmation emails
- Updates order status
- Create orders with multiple items
- Real-time inventory validation
- Automatic tax calculation (18% GST)
- Price snapshotting at purchase time
- Order status tracking (Pending → Processing → Processed)
- User registration with password hashing
- JWT-based authentication
- Refresh token mechanism
- Secure cookie-based token storage
- Outbox pattern for reliable message publishing
- Cron-based outbox processor (runs every minute)
- SQS message queue for asynchronous processing
- Idempotent message processing
- Error handling and retry mechanisms
- Automated order confirmation emails
- Beautiful HTML email templates using Mailgen
- Email delivery status tracking
- Node.js - Runtime environment
- Express.js - Web framework
- TypeScript - Type safety (order-processing-service)
- JavaScript (ES6+) - (order-service)
- MongoDB - NoSQL database
- Mongoose - ODM for MongoDB
- AWS SQS - Message queuing service
- LocalStack - Local AWS services for development
- JWT (jsonwebtoken) - Token-based authentication
- bcrypt - Password hashing
- Nodemailer - Email sending
- Mailgen - Email template generation
- MailTrap - Email testing service
- Docker Compose - Container orchestration
- node-cron - Scheduled tasks
- express-validator - Request validation
- Zod - Schema validation (TypeScript service)
OrderProcessingSystem/
├── docker-compose.yml # LocalStack configuration
├── order-service/ # Order management service
│ ├── src/
│ │ ├── app.js # Express app configuration
│ │ ├── index.js # Service entry point
│ │ ├── config/ # Configuration files
│ │ │ └── sqs-client.js # AWS SQS client setup
│ │ ├── controllers/ # Request handlers
│ │ │ ├── auth.controllers.js
│ │ │ ├── order.controllers.js
│ │ │ └── healthcheck.controllers.js
│ │ ├── db/ # Database management
│ │ │ └── db-manager.js
│ │ ├── middlewares/ # Express middlewares
│ │ │ ├── auth.middlewares.js
│ │ │ ├── customErrorHandler.middlewares.js
│ │ │ └── validate.middlewares.js
│ │ ├── models/ # Mongoose models
│ │ │ ├── order.models.js
│ │ │ ├── outbox.models.js
│ │ │ ├── product.models.js
│ │ │ └── user.models.js
│ │ ├── routes/ # API routes
│ │ │ ├── auth.routes.js
│ │ │ ├── order.routes.js
│ │ │ └── healthcheck.routes.js
│ │ ├── services/ # Business logic
│ │ │ ├── order.services.js
│ │ │ └── queue.services.js
│ │ ├── utils/ # Utility functions
│ │ │ ├── asyncHandler.js
│ │ │ ├── constants.js
│ │ │ └── customError.js
│ │ ├── validators/ # Input validation rules
│ │ │ ├── auth.validators.js
│ │ │ └── order.validators.js
│ │ └── worker/ # Background workers
│ │ └── producer.js # Outbox processor
│ ├── package.json
│ └── .env # Environment variables
│
└── order-processing-service/ # Order processing service
├── src/
│ ├── app.ts # Express app configuration
│ ├── index.ts # Service entry point
│ ├── config/ # Configuration files
│ │ ├── env.ts # Environment config
│ │ └── sqs-client.ts # AWS SQS client setup
│ ├── controllers/ # Request handlers
│ │ └── healthCheck.controllers.ts
│ ├── db/ # Database management
│ │ └── db-manager.ts
│ ├── models/ # Mongoose models
│ │ ├── order.models.ts
│ │ ├── product.models.ts
│ │ └── user.models.ts
│ ├── routes/ # API routes
│ │ └── healthCheck.routes.ts
│ ├── services/ # Business logic
│ │ ├── email.services.ts
│ │ └── messageProcessing.services.ts
│ ├── types/ # TypeScript types
│ │ ├── order.types.ts
│ │ └── sqsMessage.types.ts
│ ├── utils/ # Utility functions
│ │ ├── constants.ts
│ │ └── mailGenerator.ts
│ └── worker/ # Background workers
│ └── consumer.ts # SQS message consumer
├── package.json
├── tsconfig.json
└── .env # Environment variables
Before you begin, ensure you have the following installed:
- Node.js (v18 or higher)
- npm or yarn
- MongoDB (v6 or higher) - Running locally or connection string
- Docker and Docker Compose (for LocalStack)
- Git
git clone <repository-url>
cd OrderProcessingSystemStart the LocalStack container for local SQS development:
docker-compose up -dThis will start LocalStack on port 4566 with SQS service enabled.
After LocalStack is running, create an SQS queue:
# Using AWS CLI (configured for LocalStack)
aws --endpoint-url=http://localhost:4566 sqs create-queue \
--queue-name order-processing-queue \
--region ap-south-1Or use the LocalStack web interface at http://localhost:4566.
cd order-service
npm installCreate a .env file in order-service/:
# Server
PORT=8000
# MongoDB
MONGODB_URI=mongodb://localhost:27017/order-service
# JWT
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
JWT_REFRESH_SECRET=your-super-secret-refresh-key-change-this-in-production
JWT_EXPIRY=1h
JWT_REFRESH_EXPIRY=7d
# AWS SQS (LocalStack)
AWS_REGION=ap-south-1
AWS_ACCESS_KEY_ID=test
AWS_SECRET_ACCESS_KEY=test
SQS_QUEUE_URL=http://localhost:4566/000000000000/order-processing-queue
SQS_ENDPOINT=http://localhost:4566
# Outbox Processing
OUTBOX_PROCESSING_BATCH_SIZE=10cd ../order-processing-service
npm installCreate a .env file in order-processing-service/:
# Server
PORT=8001
# MongoDB
MONGODB_URI=mongodb://localhost:27017/order-processing-service
# AWS SQS (LocalStack)
AWS_REGION=ap-south-1
AWS_ACCESS_KEY_ID=test
AWS_SECRET_ACCESS_KEY=test
SQS_QUEUE_URL=http://localhost:4566/000000000000/order-processing-queue
SQS_ENDPOINT=http://localhost:4566
# SQS Consumer
VISIBILITY_TIMEOUT=30
BATCH_SIZE=10
# Email (MailTrap)
MAILTRAP_SMTP_HOST=smtp.mailtrap.io
MAILTRAP_SMTP_PORT=2525
MAILTRAP_SMTP_USER=your-mailtrap-username
MAILTRAP_SMTP_PASS=your-mailtrap-passwordNote: Sign up for a free MailTrap account at mailtrap.io to get SMTP credentials for email testing.
Terminal 1 - Order Service:
cd order-service
npm run devTerminal 2 - Order Processing Service:
cd order-processing-service
npm run devBoth services should now be running:
- Order Service:
http://localhost:8000 - Order Processing Service:
http://localhost:8001
| Variable | Description | Default |
|---|---|---|
PORT |
Server port | 8000 |
MONGODB_URI |
MongoDB connection string | - |
JWT_SECRET |
JWT signing secret | - |
JWT_REFRESH_SECRET |
JWT refresh token secret | - |
JWT_EXPIRY |
Access token expiry | 1h |
JWT_REFRESH_EXPIRY |
Refresh token expiry | 7d |
SQS_QUEUE_URL |
SQS queue URL | - |
OUTBOX_PROCESSING_BATCH_SIZE |
Outbox batch size | 10 |
| Variable | Description | Default |
|---|---|---|
PORT |
Server port | 8001 |
MONGODB_URI |
MongoDB connection string | - |
SQS_QUEUE_URL |
SQS queue URL | - |
VISIBILITY_TIMEOUT |
SQS visibility timeout (seconds) | 30 |
BATCH_SIZE |
SQS batch size | 10 |
MAILTRAP_SMTP_HOST |
MailTrap SMTP host | - |
MAILTRAP_SMTP_PORT |
MailTrap SMTP port | 2525 |
MAILTRAP_SMTP_USER |
MailTrap username | - |
MAILTRAP_SMTP_PASS |
MailTrap password | - |
Register User
POST /api/auth/register
Content-Type: application/json
{
"username": "john_doe",
"email": "john@example.com",
"password": "securePassword123"
}Login
POST /api/auth/login
Content-Type: application/json
{
"email": "john@example.com",
"password": "securePassword123"
}Refresh Token
POST /api/auth/refreshCreate Order (Protected)
POST /api/orders
Authorization: Bearer <access_token>
Content-Type: application/json
{
"items": [
{
"productId": "507f1f77bcf86cd799439011",
"quantity": 2
},
{
"productId": "507f1f77bcf86cd799439012",
"quantity": 1
}
]
}Get Order Details (Protected)
GET /api/orders/:id
Authorization: Bearer <access_token>GET /api/healthGET /processor/api/health-
User Authentication
- User registers/logs in through Order Service
- Receives JWT access and refresh tokens
-
Order Creation
- User sends order request with items
- Order Service validates:
- User authentication
- Product existence
- Inventory availability
- Creates order within MongoDB transaction:
- Deducts inventory
- Creates order document
- Creates outbox entry (same transaction)
- Returns order ID to user
-
Outbox Processing
- Cron job runs every minute
- Fetches pending outbox messages
- Publishes messages to SQS queue
- Marks outbox messages as processed
-
Order Processing
- Order Processing Service consumes messages from SQS
- Validates and processes order:
- Updates order status to "Processed"
- Generates order confirmation email
- Sends email via MailTrap
- Marks email as sent
The Outbox Pattern ensures reliable message delivery:
Order Creation Transaction:
├── Create Order
├── Update Inventory
└── Create Outbox Entry
└── (All in same transaction - atomic)
Outbox Processor (Cron):
├── Fetch Pending Outbox Messages
├── Publish to SQS
└── Mark as Processed
This guarantees that if an order is created, a message will eventually be published to the queue, even if the service crashes immediately after order creation.
The Order Processing Service implements idempotency checks:
- Order status is only updated if not already processed
- Email is only sent if not already sent
- Prevents duplicate processing of the same message
Both services support hot-reloading with nodemon:
# Order Service
cd order-service
npm run dev
# Order Processing Service
cd order-processing-service
npm run devThe project uses Prettier for code formatting. Format code with:
npm run format # If configured in package.jsonEnsure MongoDB is running and accessible. The services will automatically create collections on first use.
Required Collections:
users- User accountsproducts- Product catalogorders- Order recordsoutbox- Outbox messages (Order Service only)
- Create a Product (manually in MongoDB or via a script)
- Register a User via
/api/auth/register - Login to get access token
- Create an Order with the access token
- Wait for Processing - The order will be processed within 1 minute
- Check Email - Order confirmation email will be sent
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow existing code style and patterns
- Add appropriate error handling
- Include logging for debugging
- Update documentation for new features
- Ensure backward compatibility
Anubhav Jain
This project demonstrates several important concepts:
- Microservices Architecture - Service separation and communication
- Event-Driven Architecture - Asynchronous processing with message queues
- Outbox Pattern - Reliable message publishing
- Transaction Management - MongoDB transactions for data consistency
- Idempotency - Handling duplicate messages safely
- JWT Authentication - Token-based security
- Email Integration - Automated notifications
Happy Coding! 🚀