A minimal distributed system demo that uses:
- gRPC for synchronous service-to-service calls
- RabbitMQ as a message broker for asynchronous events
- Docker Compose for one-command startup
This project simulates an order → payment → notification workflow.
Client → Order Service (gRPC) → Payment Service (gRPC) → RabbitMQ → Notification Service- Order Service – Accepts CreateOrder requests and calls Payment Service via gRPC.
- Payment Service – Processes payments and publishes PaymentCompleted or PaymentFailed events to RabbitMQ.
- Notification Service – Listens to RabbitMQ events and logs a simulated “email sent” message.
- RabbitMQ – Event broker for communication between Payment and Notification services.
- Node.js 20
- gRPC + Protobuf
- RabbitMQ 3-management
- Docker Compose
- Built-in retry/backoff for broker connections
- Prerequisites
- Docker installed
- Docker Compose installed
- Port 5672 (RabbitMQ) and 50051-50052 free on your machine
- Clone the repo
git clone https://github.com/phamphihungbk/orderflow.git
cd orderflow- Build & start services
docker compose up --build- Starts RabbitMQ, Order Service, Payment Service, Notification Service
- RabbitMQ UI → http://localhost:15672 (user: guest, pass: guest)
You’ll see logs like:
[order] gRPC listening on 50051
[payment] gRPC listening on 50052
[notify] Connected. Waiting for messages in 'payments'- Run the client
Open a second terminal (still in project root):
docker compose run --rm clientExpected output:
Client response for A-1001: { status: 'PAID', message: 'Order A-1001: Payment captured' }
Client response for A-1002: { status: 'FAILED', message: 'Order A-1002: Card declined' }- Check service logs
Order Service:
[order] CreateOrder received: { order_id: 'A-1001', ... }
[order] Payment result: PAID - Payment capturedPayment Service:
[payment] Processing order A-1001 for $49.99
[payment] Published to 'payments': {...}Notification Service:
[notify] Email sent to alice@example.com: Your order A-1001 is PAID.
[notify] Email sent to bob@example.com: Your order A-1002 FAILED.- Stop all services
docker compose down -vAccess:
http://localhost:15672Login:
Username: guest
Password: guestYou can inspect the payments queue and see messages when running the client.
proto/ # Protobuf definitions
services/
order-service/ # gRPC server for orders
payment-service/ # gRPC server for payments + publishes to RabbitMQ
notification-service/ # Worker that consumes RabbitMQ messages
client/ # Simple script to call Order Service
docker-compose.yml
README.md