Microservices: Building a Simple RabbitMQ configuration with NestJS Discovery

Abdulmalik
4 min readJun 6, 2024

--

After a very long and doubtful research over the internet, I finally settled for using nestjs. For a project that was to be completed in a short time, I had to drop my “expressjs” ego to settle for a tool that can lift some weight off my back.

The application was microservice based and it comprised mainly of a CRM (Customer Relationship Management) service and an inventory service. My initial choice was to go for the default nestjs feature that allows you to establish communications between your services using HTTP, gRPC or RabbitMQ.

In this article, I’ll highlight some of the issues I faced, how the NestJS discovery system assisted and some explanations around a few important concepts. This may not be as extensive as expected, so I’ll be adding a few articles for the explorative minds.

As you’ve imagined (from the title), a typical scenario is that, when an event occurs, such as a customer changing their home address; we intend to notify the inventory service and every other service that cares. The default nestjs microservice module only allows sending messages to queues using a direct exchange, but we wanted to spice things up by adding more services and allowing them listen to various events they’re interested in.

We introduced an extra service to the mix, called payment service, which should handle every scenario around payment. There’s every possibility that this service is connected to a queue and it is also interested in knowing when a customer got their address updated.

A popular rabbitMQ mechanism to achieve this broadcast-like message routing is called topic exchanges. You can digress a bit to read this interesting article that explains these concepts in depth.

Sample case of Rabbit MQ topic exhange

Although the current nestjs feature allows you to work with a wide variety of messaging systems, therefore you might have to rely on a 3rd party package such as nestjs-rabbitmq by golevelup or create a custom one which we’ll be seeing shortly.

The custom QueueModule setup relies on these npm packages including a discovery package by golevelup:

  1. amqp-connection-manager
  2. golevelup/nestjs-discovery
  3. amqplib

Creating QueueModule.ts

The QueueModule is a typical nestjs module that is supposed to help you do the following:

  • Connect to the message Queue (RabbitMQ)
  • Scan your project from methods that subscribe (consumers) to queue events
  • Activate the subscribed methods by resolving subscriber dependencies.
  • Map subscriber methods to events.

Creating Event Producer (Emitting)

The event emitter service can be used to emit events from anywhere within your application. Notice that the QueueModule exports this service class by default, hence it is readily available.

Calling Events and listeners within Controller Services

Looking closely, you’ll realize the QueueModule tries to scan for any decorator that holds the metadata of “AMQP_SUBSCRIBER”. This decorator is what is prefixed for every service method we’re interested in.

Custom decorator to subscribe to event RMQ
Event Subscriber within a service class

Emitting Custom Events

Nestjs recommeds code or logic in modules, so the producer service would be available to a services within a module that imports the QueueModule.

Calling the Producer Service from the QueueModule
Emit event from anywhere in your application

Summary

When we use decorators with Nest, we are using them to create metadata entries to later be read and used. This is powerful because the framework can detect various parts of our application such as controllers, guards, middlewares, etc, infer their purpose and inject necessary dependencies.

Even though type reflection (Reflection API) it is not as robust as the what we have in other languages such as C#, the experimental use of decorators and reflection metadata has been huge plus within the typescript space as it improves readability and makes work easier for developers.

Happy Reading 🤓!

--

--

Abdulmalik

I've recently embraced the culture of reading, since I discovered it's equivalent to hundreds of mentors.