<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged messaging</title>
<link>https://coderlegion.com/tag/messaging</link>
<description>Powered by Question2Answer</description>
<item>
<title>Understanding RabbitMQ in Real-World .NET Systems: Why, When, and How to Use It</title>
<link>https://coderlegion.com/10115/understanding-rabbitmq-in-real-world-net-systems-why-when-and-how-to-use-it</link>
<description>&lt;p&gt;Most teams don’t start with RabbitMQ.&lt;/p&gt;
&lt;p&gt;They add it when something begins to hurt.&lt;/p&gt;
&lt;p&gt;Requests become slow.&lt;br&gt;
Failures spread across services.&lt;br&gt;
One small issue takes down multiple parts of the system.&lt;/p&gt;
&lt;p&gt;That’s usually when RabbitMQ enters the picture.&lt;/p&gt;
&lt;p&gt;This article explains what RabbitMQ actually solves, how to think about it from a senior-engineer perspective, and includes simple .NET examples to make the ideas concrete.&lt;/p&gt;
&lt;p&gt;No heavy theory.&lt;br&gt;
No marketing language.&lt;br&gt;
Just practical understanding.&lt;/p&gt;
&lt;p&gt;The Real Problem RabbitMQ Solves&lt;/p&gt;
&lt;p&gt;RabbitMQ solves tight coupling between systems.&lt;/p&gt;
&lt;p&gt;Without a message queue, systems usually communicate like this:&lt;/p&gt;
&lt;p&gt;“Do this now, and I’ll wait for the result.”&lt;/p&gt;
&lt;p&gt;That works—until it doesn’t.&lt;/p&gt;
&lt;p&gt;With RabbitMQ, communication changes to:&lt;/p&gt;
&lt;p&gt;“Here’s a message. Process it when you’re ready.”&lt;/p&gt;
&lt;p&gt;This small shift has a big impact:&lt;br&gt;
•Users don’t wait&lt;br&gt;
•Failures don’t spread&lt;br&gt;
•Systems become more resilient&lt;/p&gt;
&lt;p&gt;RabbitMQ creates space between components, and that space matters.&lt;/p&gt;
&lt;p&gt;A Simple Real-World Scenario&lt;/p&gt;
&lt;p&gt;Imagine a .NET API where a user places an order.&lt;/p&gt;
&lt;p&gt;Behind the scenes, you need to:&lt;br&gt;
•send a confirmation email&lt;br&gt;
•update inventory&lt;br&gt;
•notify another service&lt;/p&gt;
&lt;p&gt;If everything happens synchronously:&lt;br&gt;
•the API gets slower&lt;br&gt;
•one failure breaks the entire flow&lt;br&gt;
•retries become complicated&lt;/p&gt;
&lt;p&gt;With RabbitMQ:&lt;br&gt;
•the order is accepted immediately&lt;br&gt;
•background work happens later&lt;br&gt;
•each task runs independently&lt;/p&gt;
&lt;p&gt;The user moves on.&lt;br&gt;
The system stays calm.&lt;/p&gt;
&lt;p&gt;How RabbitMQ Works (Without Jargon)&lt;/p&gt;
&lt;p&gt;At a high level, the flow looks like this:&lt;/p&gt;
&lt;p&gt;Producer → Exchange → Queue → Consumer&lt;/p&gt;
&lt;p&gt;In practice:&lt;br&gt;
•Your .NET API publishes a message&lt;br&gt;
•RabbitMQ stores it safely&lt;br&gt;
•A background service consumes and processes it&lt;/p&gt;
&lt;p&gt;The producer does not need to know:&lt;br&gt;
•who consumes the message&lt;br&gt;
•how long it takes&lt;br&gt;
•whether it fails temporarily&lt;/p&gt;
&lt;p&gt;That decoupling is the real value.&lt;/p&gt;
&lt;p&gt;Publishing a Message in .NET (Simple Example)&lt;/p&gt;
&lt;p&gt;Here’s a minimal C# example using RabbitMQ.Client.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var factory = new ConnectionFactory
{
    HostName = &quot;localhost&quot;
};

using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();

channel.QueueDeclare(
    queue: &quot;order.created&quot;,
    durable: true,
    exclusive: false,
    autoDelete: false,
    arguments: null
);

var message = &quot;Order 123 created&quot;;
var body = Encoding.UTF8.GetBytes(message);

channel.BasicPublish(
    exchange: &quot;&quot;,
    routingKey: &quot;order.created&quot;,
    basicProperties: null,
    body: body
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What matters here is not the syntax.&lt;/p&gt;
&lt;p&gt;What matters is this:&lt;br&gt;
 The API sends a message and continues its work.&lt;/p&gt;
&lt;p&gt;Consuming Messages in .NET (Background Worker)&lt;/p&gt;
&lt;p&gt;Now let’s look at a simple consumer.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var factory = new ConnectionFactory
{
    HostName = &quot;localhost&quot;
};

using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();

channel.QueueDeclare(
    queue: &quot;order.created&quot;,
    durable: true,
    exclusive: false,
    autoDelete: false,
    arguments: null
);

var consumer = new EventingBasicConsumer(channel);

consumer.Received += (sender, eventArgs) =&amp;gt;
{
    var body = eventArgs.Body.ToArray();
    var message = Encoding.UTF8.GetString(body);

    Console.WriteLine($&quot;Processing: {message}&quot;);

    // Send email, update inventory, etc.
};

channel.BasicConsume(
    queue: &quot;order.created&quot;,
    autoAck: true,
    consumer: consumer
);

Console.ReadLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This consumer:&lt;br&gt;
•waits patiently&lt;br&gt;
•processes messages when they arrive&lt;br&gt;
•can be scaled independently&lt;/p&gt;
&lt;p&gt;Why This Design Works Well&lt;/p&gt;
&lt;p&gt;This pattern gives you:&lt;br&gt;
•faster user responses&lt;br&gt;
•fewer cascading failures&lt;br&gt;
•better control over background tasks&lt;/p&gt;
&lt;p&gt;If email sending fails:&lt;br&gt;
•the order is still saved&lt;br&gt;
•the message can be retried&lt;br&gt;
•users are not blocked&lt;/p&gt;
&lt;p&gt;That’s a real improvement, not just an architectural one.&lt;/p&gt;
&lt;p&gt;When RabbitMQ Is a Good Choice&lt;/p&gt;
&lt;p&gt;RabbitMQ works best when:&lt;br&gt;
•work can be asynchronous&lt;br&gt;
•reliability matters more than speed&lt;br&gt;
•services should stay independent&lt;br&gt;
•traffic comes in spikes&lt;/p&gt;
&lt;p&gt;Common use cases:&lt;br&gt;
•email and notification systems&lt;br&gt;
•background jobs&lt;br&gt;
•event-driven workflows&lt;br&gt;
•system integrations&lt;/p&gt;
&lt;p&gt;When RabbitMQ Is the Wrong Choice&lt;/p&gt;
&lt;p&gt;RabbitMQ is not always the answer.&lt;/p&gt;
&lt;p&gt;Avoid it when:&lt;br&gt;
•the system is very small&lt;br&gt;
•everything must be real-time&lt;br&gt;
•the team can’t support extra infrastructure&lt;/p&gt;
&lt;p&gt;Adding a message broker adds responsibility.&lt;br&gt;
If the problem is simple, keep the solution simple.&lt;/p&gt;
&lt;p&gt;Common Mistakes in Real Projects&lt;/p&gt;
&lt;p&gt;Some mistakes show up again and again:&lt;br&gt;
•Treating queues like databases&lt;br&gt;
•Ignoring retries and dead-letter queues&lt;br&gt;
•Writing consumers that aren’t idempotent&lt;br&gt;
•Adding async everywhere without reason&lt;/p&gt;
&lt;p&gt;RabbitMQ does not remove complexity.&lt;br&gt;
It moves complexity to where it belongs.&lt;/p&gt;
&lt;p&gt;RabbitMQ Is a Design Decision, Not a Tool Choice&lt;/p&gt;
&lt;p&gt;Senior engineers don’t choose RabbitMQ because it’s popular.&lt;/p&gt;
&lt;p&gt;They choose it because:&lt;br&gt;
•boundaries are clear&lt;br&gt;
•failures are contained&lt;br&gt;
•systems become easier to reason about&lt;/p&gt;
&lt;p&gt;RabbitMQ helps systems talk without depending on each other’s timing or health.&lt;/p&gt;
&lt;p&gt;That separation is powerful.&lt;/p&gt;
&lt;p&gt;Final Thoughts&lt;/p&gt;
&lt;p&gt;RabbitMQ is quiet technology.&lt;/p&gt;
&lt;p&gt;It doesn’t impress in demos.&lt;br&gt;
It doesn’t make headlines.&lt;/p&gt;
&lt;p&gt;But over time, it:&lt;br&gt;
•reduces incidents&lt;br&gt;
•improves reliability&lt;br&gt;
•makes systems easier to operate&lt;/p&gt;
&lt;p&gt;That’s why it stays.&lt;/p&gt;
&lt;p&gt;Good systems are not fast because they rush.&lt;br&gt;
They’re fast because they don’t block each other.&lt;/p&gt;
&lt;p&gt;That’s the real lesson RabbitMQ teaches.&lt;/p&gt;
&lt;p&gt;Thanks for reading &lt;/p&gt;
&lt;p&gt;If you’re using RabbitMQ:&lt;br&gt;
•What problem did it solve for you?&lt;br&gt;
•What lesson did you learn the hard way?&lt;/p&gt;
&lt;p&gt;Let’s discuss in the comments.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/10115/understanding-rabbitmq-in-real-world-net-systems-why-when-and-how-to-use-it</guid>
<pubDate>Wed, 21 Jan 2026 05:38:26 +0000</pubDate>
</item>
<item>
<title>EDA, Messaging, Event Sourcing, Event Storming: Resolve Terms Collision</title>
<link>https://coderlegion.com/7426/eda-messaging-event-sourcing-event-storming-resolve-terms-collision</link>
<description>&lt;p&gt;There is quite a terminology collision among these terms happening in backends. This short note concisely explains what is what, where, and what for.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Contents&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Event-Driven Architecture (EDA)&lt;ul&gt;
&lt;li&gt;Messaging&lt;/li&gt;
&lt;li&gt;Disambiguation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Event Sourcing&lt;/li&gt;
&lt;li&gt;Event Storming&lt;/li&gt;
&lt;li&gt;Overview Diagram&lt;/li&gt;
&lt;li&gt;References&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;event-driven-architecture-eda-&quot;&gt;Event-Driven Architecture (EDA)&lt;/h3&gt;
&lt;p&gt;This is an optional part of the application-level architecture &lt;sup&gt;[1]&lt;/sup&gt;. It defines one of the ways allowing an application components to communicate with each other (see also my &lt;a rel=&quot;nofollow&quot; href=&quot;https://valentineshi.dev/content/niceties/ELfn4EReRrCRQA7yGeHF-g/when-bother-with-events&quot;&gt;When Bother with Events&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The event, in this realm, is a means of communication between otherwise &lt;a rel=&quot;nofollow&quot; href=&quot;denied:&amp;lt;https://en.wikipedia.org/wiki/Coupling_(computer_programming)&amp;gt;&quot;&gt;decoupled&lt;/a&gt; (independent) components.&lt;/p&gt;
&lt;p&gt;The events are passed via event buses &lt;sup&gt;[2]&lt;/sup&gt; or message brokers &lt;sup&gt;[3]&lt;/sup&gt;.&lt;/p&gt;
&lt;h4 id=&quot;messaging&quot;&gt;Messaging&lt;/h4&gt;
&lt;p&gt;In EDA events are the same as messages, the application-level tools, not domain-level notions. The messages and events can be used interchangeably in the application context.&lt;/p&gt;
&lt;h4 id=&quot;disambiguation&quot;&gt;Disambiguation&lt;/h4&gt;
&lt;p&gt;At backends it is simpler to use term &lt;code&gt;message&lt;/code&gt; to avoid collision with a number of other &lt;code&gt;event&lt;/code&gt; terms used there. In front-ends &lt;code&gt;events&lt;/code&gt; are widely used, however the nature - means of decoupled communications among the application components - stays the same. People need a convention to understand each other. Use this one if see convenient.&lt;/p&gt;
&lt;h3 id=&quot;event-sourcing&quot;&gt;Event Sourcing&lt;/h3&gt;
&lt;p&gt;This has nothing to do with communication between application components.&lt;/p&gt;
&lt;p&gt;It is a logical persistence model that suggests recording a historical sequence of domain entity states. Events here are problem domain happenings — records of different types of domain data.&lt;/p&gt;
&lt;p&gt;They are persisted in the application database in an append-only manner (they say, &quot;a log of domain events&quot;). It contrasts with the more common approach of recording only the latest domain-entity state.&lt;/p&gt;
&lt;p&gt;They resemble a lot &quot;&lt;a rel=&quot;nofollow&quot; href=&quot;https://en.wikipedia.org/wiki/Time_series&quot;&gt;time series&lt;/a&gt;&quot; in statistical meaning with the very similar purposes. They are used to reconstruct the state of domain entities at any desired point or a period in time.&lt;/p&gt;
&lt;h3 id=&quot;event-storming&quot;&gt;Event Storming&lt;/h3&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.eventstorming.com/&quot;&gt;Event Storming&lt;/a&gt; is the problem domain events [^3] discovery method, used in &lt;a rel=&quot;nofollow&quot; href=&quot;https://en.wikipedia.org/wiki/Requirements_engineering&quot;&gt;requirements engineering&lt;/a&gt;, came to us from &lt;a rel=&quot;nofollow&quot; href=&quot;https://en.wikipedia.org/wiki/Domain-driven_design&quot;&gt;Domain-Driven Design&lt;/a&gt; (DDD).&lt;/p&gt;
&lt;p&gt;They are used for domain and application modeling. These events may or may not be further stored as history of domain event states at the application database becoming &lt;code&gt;events&lt;/code&gt; in the Event Sourcing meaning. And they may become a payload in EDA &lt;code&gt;messages&lt;/code&gt; which unpleasantly clashes with &quot;E&quot; (&lt;code&gt;events&lt;/code&gt;) of the EDA.&lt;/p&gt;
&lt;p&gt;Finally, this completely clarifies the matter.&lt;/p&gt;
&lt;h3 id=&quot;overview-diagram&quot;&gt;Overview Diagram&lt;/h3&gt;
&lt;div class=&quot;div-green&quot;&gt;
&lt;span class=&quot;alert-header&quot;&gt;[HINT]&lt;/span&gt;
&lt;span class=&quot;alert-body&quot;&gt;
Add the &lt;a rel=&quot;nofollow&quot; href=&quot;https://chromewebstore.google.com/detail/svg-navigator/pefngfjmidahdaahgehodmfodhhhofkl&quot; target=&quot;_blank&quot;&gt;SVG Navigator&lt;/a&gt; extension to your Chrome to comfortably view the diagrams with zoom and pan in the separate tab.
&lt;/span&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://ik.imagekit.io/jvipnybf9/diagram.svg&quot; target=&quot;_blank&quot;&gt;&lt;br&gt;
  &lt;img src=&quot;https://ik.imagekit.io/jvipnybf9/diagram.svg&quot; alt=&quot;overview diagram&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;p&gt;[1] See the definitions of the application (&lt;a rel=&quot;nofollow&quot; href=&quot;https://en.wikipedia.org/wiki/Service_layer_pattern&quot;&gt;service&lt;/a&gt;) level and its place in a &lt;a rel=&quot;nofollow&quot; href=&quot;https://en.wikipedia.org/wiki/Multitier_architecture&quot;&gt;multitier&lt;/a&gt; (N-tier) software architecture used in complex products. For wider context see Fowler's &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420&quot;&gt;Patterns of Enterprise Application Architecture&lt;/a&gt; (2002), p.30, Service Layer; &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215&quot;&gt;Domain-Driven Design&lt;/a&gt; (2003), p. 68, Layered Architecture.&lt;/p&gt;
&lt;p&gt;[2] In NodeJS ecosystem &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.npmjs.com/package/eventemitter3&quot;&gt;eventemitter3&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.npmjs.com/package/emittery&quot;&gt;emittery&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.npmjs.com/package/mitt&quot;&gt;mitt&lt;/a&gt;. In browsers see &lt;a rel=&quot;nofollow&quot; href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Events&quot;&gt;DOM&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Event&quot;&gt;events interface&lt;/a&gt; that principally behave the same way or &lt;a rel=&quot;nofollow&quot; href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events&quot;&gt;Server-Sent Events&lt;/a&gt; (uses persistent HTTP connection as kind if event bus).&lt;/p&gt;
&lt;p&gt;[3] [RabbitMQ](&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.rabbitmq.com/docs&quot;&gt;https://www.rabbitmq.com/docs&lt;/a&gt;) (queues and streams), &lt;a rel=&quot;nofollow&quot; href=&quot;https://kafka.apache.org/&quot;&gt;Apache Kafka&lt;/a&gt; (pub/sub via streams), &lt;a rel=&quot;nofollow&quot; href=&quot;https://nats.io/&quot;&gt;NATS&lt;/a&gt; (queue-like topics and streams) and many others.&lt;/p&gt;
</description>
<category>Backend Dev</category>
<guid isPermaLink="true">https://coderlegion.com/7426/eda-messaging-event-sourcing-event-storming-resolve-terms-collision</guid>
<pubDate>Mon, 17 Nov 2025 07:56:01 +0000</pubDate>
</item>
</channel>
</rss>