Build a fault-tolerant user registration flow using Microservices. The system must guarantee that every registered user eventually gets a "Welcome Task" created, even if the message broker (RabbitMQ) is down during the registration request.
- Services: Node.js (Express)
- Database: MongoDB (Mongoose) - Configured as a Replica Set to support Transactions.
- Broker: RabbitMQ
- Infrastructure: Docker & Docker Compose
The system implements the Transactional Outbox Pattern to ensure data consistency across distributed services.
- Endpoint:
POST /api/v1/auth/register(email, password) - Logic:
- Starts a MongoDB Session (Transaction).
- Creates a
Userdocument in theuserscollection. - Creates an
Outboxdocument containing the event payloadUSER_REGISTEREDin theoutboxcollection. - Commits the Transaction. If any operation fails, the entire transaction rolls back.
- The Relay (Background Worker):
- A separate background loop polls "pending" events from the
outboxcollection. - Publishes events to RabbitMQ.
- Updates the outbox status to
SENTonly after receiving an Acknowledgment (ACK) from RabbitMQ.
- A separate background loop polls "pending" events from the
- Detailed Documentation: Auth Service README
- Logic:
- Listens to the
user_registered_queue. - Creates a default "Welcome to the App" todo item for the registered user ID.
- Idempotency: Utilizes a
processed_eventscollection with a unique index oneventIdto ensure that duplicate messages do not result in duplicate tasks.
- Listens to the
- Detailed Documentation: Todo Service README
- Docker and Docker Compose installed.
-
Clone the repository:
git clone <repository-url> cd todo-microservice
-
Run with Docker Compose:
docker-compose up -d --build
Note: This will orchestrate the Auth Service, Todo Service, RabbitMQ, and a MongoDB Replica Set.
-
Access the Services:
- Auth Service:
http://localhost:4001 - Todo Service:
http://localhost:4002 - RabbitMQ Management:
http://localhost:15672(Guest/Guest)
- Auth Service:
To verify the fault tolerance and reliability of the system, follow these scenarios:
- Stop RabbitMQ:
docker stop rabbitmq - Register a User: Send a POST request to
http://localhost:4001/api/v1/auth/register.- Result: The registration succeeds, and the user is saved. The outbox shows a
PENDINGevent.
- Result: The registration succeeds, and the user is saved. The outbox shows a
- Start RabbitMQ:
docker start rabbitmq - Verification: After RabbitMQ comes back online, the Relay service will detect the pending event, publish it, and the Todo Service will eventually create the "Welcome Task".
- Stop Todo Service:
docker stop todo-service - Register a User: Perform a registration in the Auth Service.
- Check RabbitMQ: View the management UI; you will see the message waiting in the queue.
- Start Todo Service:
docker start todo-service - Verification: The Todo Service will consume the waiting message immediately upon startup and create the task.
- Manually publish the same
eventIdpayload to the RabbitMQ queue twice. - Verification: Check the Todo database. Only one "Welcome Task" should exist for that event ID, as the service rejects the second attempt via the
processed_eventsuniqueness check.
- Source Code: Clean modular structure with ES6+ syntax.
- Docker Configuration: Complete
docker-compose.ymlwith MongoDB Replica Set support. - API Logic: Full implementation of the Transactional Outbox and Event Consumption.