Contact Us

Micro-services communication: Rabbitmq and core – Cool Coders

Mobile App | April 19, 2021

When building micro-services it is very important to take into consideration which messaging mechanism you use. There are several ways in which micro-services communicate using different messaging protocols. Today we will focus on the AMQP messaging protocol with rabbitmq and core.

What is Rabbitmq ?

Rabbitmq is a messaging system that permits your applications communicate together using messages and queues. Rabbitmq uses the AMQP (Advanced Message Queuing Protocol) messaging protocol. It is opensource and is very robust. Rabbitmq is written in Erlang, a functional programming language created for telecommunication systems by Ericsson. Erlang is a concurrent programming language with several other features which permit it to be an ideal choice for building highly robust and resilient messaging systems.

How Rabbitmq Works

As we mentioned earlier, Rabbitmq implements the AMQP protocol. Here is a brief overview of how messages are sent via rabbitmq. An application willing to send messages (Producer) to another application, does so through a broker (Rabbitmq). The broker then receives the message via an Exchange which is then responsible for routing that message to appropriate Queues using routing keys and rules called bindings. The message is then received by another application which subscribes to the given queue (Consumer). You can learn more about this process here.

Some other attributes of this communication process could be configured, like sending acknowledgements when a message is received, persisting a queue in a database e.t.c. There are several types of exchanges in Rabbitmq and each determines the way in which your message is routed to corresponding queues.

Rabbitmq and Core

Though rabbitmq seams a little bit complicated in the beginning, there are awesome libraries which abstract all of these AMQP notions and make it easier to use when building your core microservices. We will use one of these libraries (Masstransit).

Installing Rabbitmq

It is easy to install rabbitmq, you can download it directly from their website and install it on your operating system. Or your could use a docker container. We will be using the later approach. The image’s name is:

Here is the command to run rabbitmq on docker. You can configure the password and username to what you wish.

docker run d t it hostname myrabbitmq name rabbitmq3server p 15672:15672 p 5672:5672 e RABBITMQ_DEFAULT_USER=user e RABBITMQ_DEFAULT_PASS=password e RABBITMQ_DEFAULT_VHOST=my_vhost rabbitmq:3management

What we will build

To demonstrate micro-services communication, we will build two simple rest APIs which will communicate with each other. One will be the users service and the other will be the companies service. The users service will receive API calls to subscribe to specific companies. Once it receives a call, it asynchronously tells the companies service to add the user to the list of subscribers in the specified company “Command”. Thereafter, the companies service broadcasts a message telling the subscription process is over “Event”. All these through rabbitmq and core.

Masstransit and its Rabbitmq abstraction layer

Rabbitmq has a library which permits us to communicate in a raw fashion. Using the notions of queues and exchanges, listening for messages with loops and all the like. Though we can perfectly use this when communicating between our micro-services, it will require much work, and what if in the future we want to change the messaging system from Rabbitmq to Servicebus or something else ? What if we want to do things in a clean an maintainable way ?.

Masstransit is a library which provides a good layer of abstraction above rabbitmq and other messaging tools. Switching from rabbitmq to another tool will just be a matter of changing configurations.

Messages are sent using Events and Commands. A command is a message sent to a specific endpoint. And an events are sent to who so ever is willing subscribed to them. To receive a message, you need to subscribe a consumer, this processes the message. When a message is sent with masstransit via rabbitmq, it is sent to an exchange with the name corresponding to the type of the message’s class. Messages sent contain metadata about the message.

If you like this post, don’t hesitate to follow me on Twitter or Github and subscribe to this page’s notifications to stay updated with new articles or like my page on Facebook.

Let’s code

The source code for this post is found here.

First, we need to add mass-transit to our services. The code bellow will not only initialize configurations for rabbitmq and masstransit, but also set up our consumers and start the bus service.

                var port = Convert.ToUInt16(configSections[“Port”]);
                    var bus = Bus.Factory.CreateUsingRabbitMq(cfg =>
                        cfg.Host(host, port, virtualHost, host =>
                        cfg.ReceiveEndpoint(configSections[“Endpoint”], ep =>
                            ep.PrefetchCount = Convert.ToUInt16(configSections[“PrefetchCount”]);
                    return bus;
            services.Configure<HealthCheckPublisherOptions>(options =>
                options.Delay = TimeSpan.FromSeconds(2);
                options.Predicate = (check) => check.Tags.Contains(“ready”);

As mentioned earlier, we will send messages via events/commands. These are simple classes containing the data we want to send.

We use only asynchronous communication here. Commands are sent while targeting specific endpoints as seen below.

public async Task SendMessage<T>(T message, string targetEndPoint)
            var endpoint = $“rabbitmq://{_rabbitConfig.Host}:{_rabbitConfig.Port}/{targetEndPoint}?durable={_rabbitConfig.DurableQueue}”;
            var finalEndpoint = await _sendEndpoint.GetSendEndpoint(new Uri(endpoint));
            await finalEndpoint.Send(message);

As you can see above, you can set an option (?durable=) specifying if you want Rabbitmq to persist a queue. Note that, an endpoint so that it persists messages it receives.

Sending events doesn’t require you to specify any endpoint. You just publish it to who so ever wants to listen to it. As shown below:

                    CompanyId = context.Message.CompanyId,
                    UserId = context.Message.UserId

Now receiving messages is just as easy. You just need to create a consumer for the specific message you are willing to receive and register it as we can see above in the startup class. You can see below.

        public SubscribeToCompanyConsumer(IOptions<RabbitmqConfig> rabbitConfig,
            _store = store;
        public Task Consume(ConsumeContext<SubscribeToCompanyCommand> context)
                var company = _store.Companies.SingleOrDefault(c => c.Id == context.Message.CompanyId);

Above we have a quick start guide to implement micro-services communication with rabbitmq and core and masstransit. You can get the source code from here. You might be interested by this article about setting optional form body in core web api.

Follow me on social media and stay updated

Share This Post On:

This content was originally published here.