RabbitMQ
import { EventEmitter } from "events";
// Step 1: Define the Abstract Domain Event
abstract class DomainEvent<T> {
constructor(public data: T) {}
}
// Step 2: Create a Generic Event Emitter
class EventDispatcher {
constructor(private channel) {}
// Step 3: Publish Domain Events
async publish<T>(event: DomainEvent<T>, exchangeName: string) {
const queueName = event.name;
const channel = await this.connection.createChannel();
await channel.assertQueue(queueName, { durable: true });
channel.sendToQueue(queueName, Buffer.from(JSON.stringify(event.data)));
}
// Step 4: Subscribe to Domain Events
async subscribe<T>(
eventType: { new (...args: any[]): DomainEvent<T> },
exchangeName: string,
callback: (event: DomainEvent<T>) => void
) {
const queueName = event.name;
const channel = await this.connection.createChannel();
await channel.assertQueue(queueName, { durable: true });
channel.consume(queueName, async function (msg: any) {
const input = JSON.parse(msg.content.toString());
try {
await callback(input);
channel.ack(msg);
} catch (e: any) {
console.log(e.message);
}
});
}
}
// Step 5: Send Welcome Email
class EmailService {
sendWelcomeEmail(userEmail: string) {
// Implement your email sending logic here
console.log(`Sending a welcome email to: ${userEmail}`);
}
}
// Usage
const connection = await amqp.connect("amqp://localhost"); // Replace with your RabbitMQ server URL
const channel = await connection.createChannel();
const eventDispatcher = new EventDispatcher(channel);
const emailService = new EmailService();
// Define specific event types for user creation and order creation
class UserCreatedEvent extends DomainEvent<{
userName: string;
email: string;
}> {}
// Subscribe to the UserCreated event and send a welcome email
eventDispatcher.subscribe(UserCreatedEvent, "userExchange", (event) => {
console.log(
`User created - Name: ${event.data.userName}, Email: ${event.data.email}`
);
emailService.sendWelcomeEmail(event.data.email);
});
// Simulate a user being created
const newUserEvent = new UserCreatedEvent({
userName: "John Doe",
email: "john@example.com",
});
eventDispatcher.publish(newUserEvent);