RabbitMQ is a message broker that enables services to send messages to each other via queues, allowing asynchronous, decoupled communication.
Instead of one service calling another directly, it publishes a message to a queue — and other services subscribe to that queue and act upon it.
Add this service to your main docker-compose.yml (you’ll complete this in Epoch 9 — for now, run it separately):
1
2
3
4
5
6
7
version: '3'
services:
rabbitmq:
image: rabbitmq:3-management
ports:
- "5672:5672" # AMQP protocol
- "15672:15672" # Management UI
Start RabbitMQ:
1
docker compose -f rabbitmq-docker.yml up -d
In the order-service:
1
npm install amqplib
In utils/rabbitmq.js:
1
2
3
4
5
6
7
8
9
10
11
12
13
import amqplib from 'amqplib';
let channel;
export async function connectRabbitMQ() {
const connection = await amqplib.connect('amqp://localhost');
channel = await connection.createChannel();
await channel.assertQueue('order_created');
}
export function publishOrderCreated(order) {
channel.sendToQueue('order_created', Buffer.from(JSON.stringify(order)));
}
In controller after order.save()
1
2
3
4
5
6
7
8
import { publishOrderCreated } from '../utils/rabbitmq.js';
await publishOrderCreated({
orderId: order._id,
userId: order.userId,
totalItems: order.items.length,
createdAt: order.createdAt,
});
Call connectRabbitMQ() when server starts.
1
npm install amqplib
In src/consumer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import amqplib from 'amqplib';
async function consumeNotifications() {
const conn = await amqplib.connect('amqp://localhost');
const channel = await conn.createChannel();
await channel.assertQueue('order_created');
channel.consume('order_created', (msg) => {
const content = JSON.parse(msg.content.toString());
console.log('🔔 Received Order Event:', content);
channel.ack(msg);
});
}
consumeNotifications();
Run this file along with the notification server:
1
node src/consumer.js