{"id":2015,"date":"2023-07-17T11:12:49","date_gmt":"2023-07-17T11:12:49","guid":{"rendered":"http:\/\/waqar-arshad.com\/?p=2015"},"modified":"2023-07-17T11:12:49","modified_gmt":"2023-07-17T11:12:49","slug":"what-is-masstransit","status":"publish","type":"post","link":"http:\/\/waqar-arshad.com\/index.php\/2023\/07\/17\/what-is-masstransit\/","title":{"rendered":"What is MassTransit?"},"content":{"rendered":"<div class=\"pld-like-dislike-wrap pld-template-1\">\r\n    <div class=\"pld-like-wrap  pld-common-wrap\">\r\n    <a href=\"javascript:void(0)\" class=\"pld-like-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"2015\" data-trigger-type=\"like\" data-restriction=\"cookie\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-up\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-like-count-wrap pld-count-wrap\">    <\/span>\r\n<\/div><div class=\"pld-dislike-wrap  pld-common-wrap\">\r\n    <a href=\"javascript:void(0)\" class=\"pld-dislike-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"2015\" data-trigger-type=\"dislike\" data-restriction=\"cookie\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-down\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-dislike-count-wrap pld-count-wrap\"><\/span>\r\n<\/div><\/div>\n<p><strong>What is RabbitMQ?<\/strong><strong><\/strong><\/p>\n\n\n\n<p>To very briefly recap, RabbitMQ is a message broker, which handles the accepting, storing, and sending of messages between our applications. Using a message broker allows us to build decoupling, performant applications, relying on asynchronous communication between our applications.<\/p>\n\n\n\n<p><strong>What Are RabbitMQ Exchanges?<\/strong><strong><\/strong><\/p>\n\n\n\n<p>When working with RabbitMQ, producers can send messages to a couple of different endpoints:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Queues<\/li>\n\n\n\n<li>Exchanges<\/li>\n<\/ul>\n\n\n\n<p>As we have covered queues in the previous article, we are going to focus just on exchanges. When a producer sends directly to a queue, this message will be received by all consumers of that queue. But what if we want to selectively send messages to different queues based on metadata found in the message? This is where exchanges come into play.<\/p>\n\n\n\n<p>An exchange receives messages from producers, and depending on its configuration, will send the message to one or many queues. We must create a&nbsp;<strong>binding<\/strong>, which will ensure our messages get sent from our exchange to one or many queues.<\/p>\n\n\n\n<p>We can define exchanges from one of the following types:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Direct<\/li>\n\n\n\n<li>Topic<\/li>\n\n\n\n<li>Headers<\/li>\n\n\n\n<li>Fanout<\/li>\n<\/ul>\n\n\n\n<p>For this article, we will focus on the&nbsp;<strong>Fanout<\/strong>&nbsp;type, as that is what MassTransit uses by default. The fanout exchange type is very simple. It will just broadcast all the messages it receives to all the queues that have created a binding with it.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"345\" src=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/07\/image-56.png\" alt=\"\" class=\"wp-image-2018\" srcset=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/07\/image-56.png 940w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/07\/image-56-300x110.png 300w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/07\/image-56-768x282.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2022\/03\/RabbitMQExchanges.drawio-1.png\"><strong><\/strong><\/a><\/p>\n\n\n\n<p><strong>What is MassTransit?<\/strong><strong><\/strong><\/p>\n\n\n\n<p><a href=\"https:\/\/masstransit-project.com\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>MassTransit<\/strong><\/a>&nbsp;is a free, open-source, distributed application framework for .NET applications.&nbsp;<strong>It abstracts away the underlying logic required to work with message brokers, such as RabbitMQ, making it easier to create message-based, loosely coupled applications<\/strong>.<\/p>\n\n\n\n<p>There are a few fundamental concepts we should cover first:<\/p>\n\n\n\n<p><strong>Service Bus,<\/strong>&nbsp;usually shortened to&nbsp;<strong>Bus<\/strong>, is the term given to the type of application that handles the movement of messages.<\/p>\n\n\n\n<p><strong>Transports&nbsp;<\/strong>are the different types of message brokers MassTransit works with, including RabbitMQ, InMemory, Azure Service Bus, and more.<\/p>\n\n\n\n<p><strong>Message&nbsp;<\/strong>is&nbsp;a contract, defined&nbsp;<em>code first&nbsp;<\/em>by creating a .NET class or interface.<\/p>\n\n\n\n<p><strong>Command&nbsp;<\/strong>is&nbsp;a type of message, specifically used to tell a service to do something. These message types are&nbsp;<strong>sent<\/strong>&nbsp;to an endpoint (queue) and will be expressed using a verb-noun sequence.<\/p>\n\n\n\n<p><strong>Events<\/strong>&nbsp;are another message type, signifying that something has happened. Events are&nbsp;<strong>published<\/strong>&nbsp;to one or multiple consumers and will be expressed using noun-verb (past tense) sequence.<\/p>\n\n\n\n<p><strong>Why Use MassTransit?<\/strong><strong><\/strong><\/p>\n\n\n\n<p>There are a few benefits to choosing to use a library such as MassTransit, instead of working with the native message broker library. Firstly,&nbsp;<strong>by abstracting the underlying message broker logic, we can work with multiple message brokers<\/strong>, without having to completely rewrite our code. This allows us to work with something such as the InMemory transport when working locally, then when deploying our code, use another transport such as Azure Service Bus or Amazon Simple Queue Service.<\/p>\n\n\n\n<p>Additionally, when we work with a message-based architecture,<strong>&nbsp;there are a lot of specific patterns we need to be aware of and implement, such as&nbsp;<em>retry<\/em>,&nbsp;<em>circuit breaker<\/em>,&nbsp;<em>outbox&nbsp;<\/em>to name a few. MassTransit handles all of this for us<\/strong>, along with many other features such as&nbsp;<em>exception handling<\/em>,&nbsp;<em>distributed transactions<\/em>, and&nbsp;<em>monitoring<\/em>.<\/p>\n\n\n\n<p>Now that we have an understanding of what MassTransit is and why we would use it, let\u2019s see how we can use it along with RabbitMQ in ASP.NET Core.<\/p>\n\n\n\n<p><strong>Implementing MassTransit With RabbitMQ in ASP.NET Core<\/strong><strong><\/strong><\/p>\n\n\n\n<p>Let\u2019s start by installing&nbsp;<a href=\"https:\/\/code-maze.com\/aspnetcore-rabbitmq\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>RabbitMQ<\/strong><\/a>.<\/p>\n\n\n\n<p><strong>Installing RabbitMQ<\/strong><strong><\/strong><\/p>\n\n\n\n<p>Before we start creating our application, we will first need to spin up a RabbitMQ server, by making use of Docker. Given that Docker is installed, we\u2019ll open a&nbsp; command-line terminal and use the&nbsp;docker run&nbsp;command to spin up our server:<\/p>\n\n\n\n<p>docker run -d &#8211;hostname my-rabbitmq-server &#8211;name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3-management<\/p>\n\n\n\n<p>We are using the&nbsp;rabbitmq:3-management&nbsp;image from&nbsp;<a href=\"https:\/\/hub.docker.com\/_\/rabbitmq\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>DockerHub<\/strong><\/a>&nbsp;which will provide us with a UI, available on port&nbsp;<strong>15672<\/strong>. We must also add a port mapping for&nbsp;<strong>5672<\/strong>, which is the default port RabbitMQ uses for communication.&nbsp;In order for us to access the management UI, we open a browser window and navigate to&nbsp;localhost:15672, using the default login of&nbsp;<strong>guest\/guest<\/strong>. We will come back to this management UI later to see what MassTransit creates for us in RabbitMQ.<\/p>\n\n\n\n<p><strong>Creating a Shared Class Library<\/strong><strong><\/strong><\/p>\n\n\n\n<p>If you remember back to the concepts of MassTransit, when we use&nbsp;<strong>Messages<\/strong>, we must define a .NET class or interface. MassTransit includes the namespace for message contracts, so we can use a shared class\/interface to set up our bindings correctly.<\/p>\n\n\n\n<p>With this in mind, the first thing we are going to do is create a class library that will contain the shared interface that we will use for our&nbsp;<strong>Producer&nbsp;<\/strong>and&nbsp;<strong>Consumer&nbsp;<\/strong>applications.<\/p>\n\n\n\n<p>We will first create a class library, which we will call&nbsp;SharedModels, within which we will define an interface:<\/p>\n\n\n\n<p>public interface OrderCreated<\/p>\n\n\n\n<p><strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; int Id <strong>{<\/strong> get; set; <strong>}<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; string ProductName <strong>{<\/strong> get; set; <strong>}<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; decimal Price <strong>{<\/strong> get; set; <strong>}<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; int Quantity <strong>{<\/strong> get; set; <strong>}<\/strong><\/p>\n\n\n\n<p><strong>}<\/strong><\/p>\n\n\n\n<p>We are using the past tense for the interface name, which indicates that this is an&nbsp;<strong>event&nbsp;<\/strong>message type. This is everything we need for our&nbsp;SharedModels&nbsp;class library. Next up, we will implement our Producer.<\/p>\n\n\n\n<p><strong>Creating a Producer Using MassTransit<\/strong><strong><\/strong><\/p>\n\n\n\n<p>Let\u2019s create our Producer, which we will implement as an ASP.NET Core Web API. The first thing we want to do is add a project reference to our&nbsp;SharedModels&nbsp;class library.<\/p>\n\n\n\n<p>Next up, we need to add a couple of Nuget packages for MassTransit:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>MassTransit<\/li>\n\n\n\n<li>MassTransit.AspNetCore<\/li>\n\n\n\n<li>MassTransit.RabbitMQ<\/li>\n<\/ul>\n\n\n\n<p>Now let\u2019s configure MassTransit to use RabbitMQ in&nbsp;Program.cs:<\/p>\n\n\n\n<p>var builder = WebApplication.CreateBuilder<strong>(<\/strong>args<strong>)<\/strong>;<\/p>\n\n\n\n<p>builder.Services.AddMassTransit<strong>(<\/strong>x =<strong>&gt;<\/strong><\/p>\n\n\n\n<p><strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; x.UsingRabbitMq<strong>()<\/strong>;<\/p>\n\n\n\n<p><strong>})<\/strong>;<\/p>\n\n\n\n<p>builder.Services.AddMassTransitHostedService<strong>()<\/strong>;<\/p>\n\n\n\n<p><strong>NOTE: For the newest versions of the MassTransit package, you can ignore the&nbsp;<\/strong>builder.Services.AddMassTransitHostedService()<strong>&nbsp;line.<\/strong><\/p>\n\n\n\n<p>First, we create our&nbsp;WebApplicationBuilder.<\/p>\n\n\n\n<p>Next up we configure MassTransit to use RabbitMQ. As this is our Producer, and RabbitMQ is going to be running on&nbsp;localhost, we don\u2019t need to define any more configuration here. The final step is to call&nbsp;AddMassTransitHostedService, which automatically handles the starting\/stopping of the bus (you don\u2019t have to do this for the newest library version).<\/p>\n\n\n\n<p>Before we create an API controller,&nbsp;we must first create an&nbsp;OrderDto&nbsp;class, which will be used as a parameter for our endpoint method:<\/p>\n\n\n\n<p>public class OrderDto<\/p>\n\n\n\n<p><strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public string ProductName <strong>{<\/strong> get; set; <strong>}<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public decimal Price <strong>{<\/strong> get; set; <strong>}<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public int Quantity <strong>{<\/strong> get; set; <strong>}<\/strong><\/p>\n\n\n\n<p><strong>}<\/strong><\/p>\n\n\n\n<p>With MassTransit configured to use&nbsp;<a href=\"https:\/\/code-maze.com\/aspnetcore-rabbitmq\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>RabbitMQ<\/strong><\/a>&nbsp;and our DTO defined, let\u2019s now create an API controller that will publish a message, or more specifically an&nbsp;<strong>event<\/strong>, using our&nbsp;OrderCreated&nbsp;interface:<\/p>\n\n\n\n<p><strong>[<\/strong>ApiController<strong>]<\/strong><\/p>\n\n\n\n<p><strong>[<\/strong>Route<strong>(<\/strong>&#8220;api\/[controller]&#8221;<strong>)]<\/strong><\/p>\n\n\n\n<p>public class OrdersController : ControllerBase<\/p>\n\n\n\n<p><strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; private readonly IPublishEndpoint _publishEndpoint;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public OrdersController<strong>(<\/strong>IPublishEndpoint publishEndpoint<strong>)<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _publishEndpoint = publishEndpoint;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>}<\/strong><\/p>\n\n\n\n<p><strong>}<\/strong><\/p>\n\n\n\n<p>The first thing we must do is inject an&nbsp;IPublishEndpoint&nbsp;into our controller, which is what we\u2019ll use to publish our event.<\/p>\n\n\n\n<p>Now we can create an endpoint for creating an order:<\/p>\n\n\n\n<p><strong>[<\/strong>HttpPost<strong>]<\/strong><\/p>\n\n\n\n<p>public async Task<strong>&lt;<\/strong>IActionResult<strong>&gt;<\/strong> CreateOrder<strong>(<\/strong>OrderDto orderDto<strong>)<\/strong><\/p>\n\n\n\n<p><strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; await _publishEndpoint.Publish<strong>&lt;<\/strong>OrderCreated<strong>&gt;(<\/strong>new<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Id = 1,<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; orderDto.ProductName,<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; orderDto.Quantity,<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; orderDto.Price<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>})<\/strong>;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; return Ok<strong>()<\/strong>;<\/p>\n\n\n\n<p><strong>}<\/strong><\/p>\n\n\n\n<p>The first thing we must do is create a new method called&nbsp;CreateOrder, and decorate it with the&nbsp;HttpPost&nbsp;attribute. This method will take our&nbsp;OrderDto&nbsp;as a parameter. Within the method, we call the generic&nbsp;Publish&nbsp;method on the&nbsp;IPublishEndpoint&nbsp;interface, using our&nbsp;OrderCreated&nbsp;interface to define what type of event we are going to be publishing.<\/p>\n\n\n\n<p>We can then create an anonymous type, ensuring we use the same property names that are defined in our&nbsp;OrderCreated&nbsp;interface. This is all we require to publish an event to our configured transport, RabbitMQ.<\/p>\n\n\n\n<p>Finally, we will return an&nbsp;OkResult.<\/p>\n\n\n\n<p><strong>Creating a Consumer Using MassTransit<\/strong><strong><\/strong><\/p>\n\n\n\n<p>Now that we have our Producer in place, we\u2019ll take a look at creating a very simple Consumer, using a .NET console application.<\/p>\n\n\n\n<p>Within the same solution, let\u2019s create a console application called&nbsp;Consumer. Like our Producer application, we must add a project reference to our&nbsp;SharedModels&nbsp;class library. We must also add a couple of Nuget packages for MassTransit:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>MassTransit<\/li>\n\n\n\n<li>MassTransit.RabbitMQ<\/li>\n<\/ul>\n\n\n\n<p>This time, we don\u2019t need the&nbsp;MassTransit.AspNetCore&nbsp;package, as we won\u2019t be making use of dependency injection in this project.<\/p>\n\n\n\n<p>With the references correctly added, we first need to create a Consumer implementation, that will contain the logic for what we want to do with any message received:<\/p>\n\n\n\n<p>class OrderCreatedConsumer : IConsumer<strong>&lt;<\/strong>OrderCreated<strong>&gt;<\/strong><\/p>\n\n\n\n<p><strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public async Task Consume<strong>(<\/strong>ConsumeContext<strong>&lt;<\/strong>OrderCreated<strong>&gt;<\/strong> context<strong>)<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var jsonMessage = JsonConvert.SerializeObject<strong>(<\/strong>context.Message<strong>)<\/strong>;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine<strong>(<\/strong>$&#8221;OrderCreated message: {jsonMessage}&#8221;<strong>)<\/strong>;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>}<\/strong><\/p>\n\n\n\n<p><strong>}<\/strong><\/p>\n\n\n\n<p>First, we create a class called&nbsp;OrderCreatedConsumer, ensuring we implement the&nbsp;IConsumer&nbsp;generic interface provided by MassTransit, using our&nbsp;OrderCreated&nbsp;interface defined in our ShareModels library. In the&nbsp;Consume&nbsp;method, we can simply serialize the message object and log the message to the console for the purposes of this article.<\/p>\n\n\n\n<p>Now that our Consumer class is defined, let\u2019s configure our Consumer to use MassTransit in&nbsp;Program.cs:&nbsp;<\/p>\n\n\n\n<p>var busControl = Bus.Factory.CreateUsingRabbitMq<strong>(<\/strong>cfg =<strong>&gt;<\/strong><\/p>\n\n\n\n<p><strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; cfg.ReceiveEndpoint<strong>(<\/strong>&#8220;order-created-event&#8221;, e =<strong>&gt;<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.Consumer<strong>&lt;<\/strong>OrderCreatedConsumer<strong>&gt;()<\/strong>;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>})<\/strong>;<\/p>\n\n\n\n<p><strong>})<\/strong>;<\/p>\n\n\n\n<p>We create an&nbsp;IBusControl, using the static&nbsp;Bus&nbsp;class provided by MassTransit, which we\u2019re going to configure to use RabbitMQ. We must then configure the&nbsp;ReceiveEndpoint, which will receive messages from the&nbsp;order-created-event&nbsp;queue. Finally, we use our previously created&nbsp;OrderCreatedConsumer&nbsp;to consume messages from this queue.<\/p>\n\n\n\n<p>With our Consumer configured to receive messages, the final thing we need to do is start our bus:<\/p>\n\n\n\n<p>await busControl.StartAsync<strong>(<\/strong>new CancellationToken<strong>())<\/strong>;<\/p>\n\n\n\n<p>try<\/p>\n\n\n\n<p><strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; Console.WriteLine<strong>(<\/strong>&#8220;Press enter to exit&#8221;<strong>)<\/strong>;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; await Task.Run<strong>(()<\/strong> =<strong>&gt;<\/strong> Console.ReadLine<strong>())<\/strong>;<\/p>\n\n\n\n<p><strong>}<\/strong><\/p>\n\n\n\n<p>finally<\/p>\n\n\n\n<p><strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; await busControl.StopAsync<strong>()<\/strong>;<\/p>\n\n\n\n<p><strong>}<\/strong><\/p>\n\n\n\n<p>First, we call&nbsp;StartAsync&nbsp;on our&nbsp;busControl, passing in a new&nbsp;CancellationToken. Now we set up the console app to run without exiting until a&nbsp;Console.ReadLine&nbsp;is registered. The final step is to ensure we stop our&nbsp;busControl&nbsp;by calling&nbsp;StopAsync.<\/p>\n\n\n\n<p><strong>Testing Our Application<\/strong><strong><\/strong><\/p>\n\n\n\n<p>Now it\u2019s time to test our code. Ensuring we have both the Producer and Consumer applications set up run on startup, hitting&nbsp;<strong>F5<\/strong>&nbsp;will open a web browser (Producer) and a console window (Consumer). Next, we can send a POST request to&nbsp;https:\/\/localhost:7188\/api\/orders, providing an order in the request body:<\/p>\n\n\n\n<p><strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; &#8220;productName&#8221;: &#8220;keyboard&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; &#8220;quantity&#8221;: 1<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; &#8220;price&#8221;: 99.99<\/p>\n\n\n\n<p><strong>}<\/strong><\/p>\n\n\n\n<p>Let\u2019s look at our console window, and we will see that our Producer correctly sent a message to RabbitMQ which our Consumer has successfully received:<\/p>\n\n\n\n<p>OrderCreated message: {&#8220;Id&#8221;: 1, &#8220;ProductName&#8221;: &#8220;keyboard&#8221;, &#8220;Price&#8221;: 99.99, &#8220;Quantity&#8221;: 1}<\/p>\n\n\n\n<p>Furthermore, we can navigate to our RabbitMQ management UI, to see what exchanges MassTransit has created for us:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"420\" height=\"259\" src=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/07\/image-57.png\" alt=\"\" class=\"wp-image-2019\" srcset=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/07\/image-57.png 420w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/07\/image-57-300x185.png 300w\" sizes=\"auto, (max-width: 420px) 100vw, 420px\" \/><\/figure>\n\n\n\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2022\/03\/masstransit-exchanges-2.png\"><strong><\/strong><\/a><\/p>\n\n\n\n<p>We should be able to see 2 exchanges created, both with the fanout type. One for the&nbsp;SharedModels:OrderCreated&nbsp;event type, which uses the namespace and model name from our shared library. We also have one for the receive endpoint we defined in our Consumer,&nbsp;order-created-event, which has a binding to the&nbsp;SharedModels:OrderCreated&nbsp;exchange.<\/p>\n\n\n\n<p>And we can also check what queues were created:&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"319\" height=\"214\" src=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/07\/image-58.png\" alt=\"\" class=\"wp-image-2020\" srcset=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/07\/image-58.png 319w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/07\/image-58-300x201.png 300w\" sizes=\"auto, (max-width: 319px) 100vw, 319px\" \/><\/figure>\n\n\n\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2022\/03\/masstransit-queues-1.png\"><strong><\/strong><\/a><\/p>\n\n\n\n<p>&nbsp;We can see our queue,&nbsp;order-created-event&nbsp;created, which has a binding to the exchange of the same name.<\/p>\n\n\n\n<p><strong>Conclusion<\/strong><strong><\/strong><\/p>\n\n\n\n<p>In this article, we\u2019ve learned about a more advanced feature of RabbitMQ, exchanges. We also had a look at the MassTransit library, and why we would choose to use it over one of the native message broker libraries. Finally, we brought this altogether by learning how to create a Producer and Consumer using MassTransit and RabbitMQ.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>What is RabbitMQ? To very briefly recap, RabbitMQ is a message broker, which handles the accepting, storing, and sending of messages between our applications. Using a message broker allows us to build decoupling, performant applications, relying on asynchronous communication between our applications. What Are RabbitMQ Exchanges? When working with RabbitMQ, producers can send messages to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[38],"tags":[],"class_list":["post-2015","post","type-post","status-publish","format-standard","hentry","category-message-bus"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"admin","author_link":"http:\/\/waqar-arshad.com\/index.php\/author\/waqar_29_1\/"},"uagb_comment_info":28,"uagb_excerpt":"What is RabbitMQ? To very briefly recap, RabbitMQ is a message broker, which handles the accepting, storing, and sending of messages between our applications. Using a message broker allows us to build decoupling, performant applications, relying on asynchronous communication between our applications. What Are RabbitMQ Exchanges? When working with RabbitMQ, producers can send messages to&hellip;","_links":{"self":[{"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/posts\/2015","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/comments?post=2015"}],"version-history":[{"count":1,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/posts\/2015\/revisions"}],"predecessor-version":[{"id":2021,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/posts\/2015\/revisions\/2021"}],"wp:attachment":[{"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/media?parent=2015"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/categories?post=2015"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/tags?post=2015"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}