in Coding

Messages vs. Events vs. Commands

In a distributed environment, services must communicate with each other. One of the most popular ways of communication is messaging. Tools like ActiveMQ, RabbitMQ or Kafka are making it easy to exchange messages between systems. But no matter which broker you are using, you must decide which kind of message you want to send.

Messages

Message brokers deal with messages. They are the basic unit of communication and can literally be anything. An ID, a string, an object, a command, an event or whatever. Messages have no special intent.

Having no special intent makes messages generic but also less meaningful. That’s why we can use two more concepts on top of messages.

Events

An event is a message which informs various listeners about something which has happened. It’s send by a producer which doesn’t know and doesn’t care about the consumers of the event.

Example: A typical example would be an online shop. Whenever an order is placed, the shop would publish an OrderSubmittedEvent to inform other systems (e.g. the logistics system) about the new order. However, the shop doesn’t care – or even know – about the consumers. If the logistics system isn’t interested in the events anymore, it just unsubscribes from the list of consumers.

⇒ In the world of JMS, events would be messages send to a topic.
⇒ The dependency goes from the consumer to the producer.

Commands

A command on the order side is much more specific. It’s a one-to-one connection between a producer (who sends the command) and a consumer (who takes and executes the command).

Example: In case of an online shop, one such example could be the BillCustomerCommand. After an order is placed, the online shop sends this command to the billing system to trigger the invoice.

⇒ In the world of JMS, commands would be messages send to a queue.
⇒ The dependency goes from the producer to the consumer.

The intent

The difference between messages, events and commands lies in their intent. While messages have no special intent at all, events inform about something which has happened and is already completed (in the past). Commands trigger something which should happen (in the future).

More

Best regards,
Thomas

Leave a Reply for Peter R Cancel Reply

Write a Comment

Comment

  1. There are a few typos in this sentence:
    “In case of an online shop, such a command might the BillCustomerCommand. After an order is places, the online shop sends this command to the billing system to trigger the invoice.”

    Proposal:
    “In case of an online shop, one such example could be the BillCustomerCommand. After an order is placed, the online shop sends this command to the billing system to trigger the invoice.”

  2. This is insanely inaccurate, as far as the real-world meaning of messages, events and commands goes.
    Messages are just information. They convey intent as well in a broad sense, but are not time critical.
    Events ARE time critical – that the originator of the event doesn’t care about the consumers is completely incorrect – the largest numbers of events are generated DEPENDING on who the consumer is (and based on the intent)
    Commands are imperative and imply a hierarchy. They ‘should’ not happen – they ‘must’ be executed (or there are ramifications – at the very least to the relationship)
    How can computing guys, being so smart, be so wrong about the most basic of basics?

    • I see your points and I don’t think that we’ve a completely different understanding of the concepts. I agree that messages are information in a broad sense. Events and commands have much more semantic. That’s why I say they’re a specialised type of message. I also agree that commands are imperative, imply hierarchy and must happen. As I wrote, commands are send from a producer directly to a consumer to trigger some operation.

      However, I strongly disagree with two points. One is that events are time critical and the other is that the originator of an event cares about the consumers. Both points go hand in hand. It’s important to understand that events are like a log of things that happened. Every time something has been done, a new log entry (an event) is written. OrderSubmitted, FlightCancelled, NameChanged… Everybody can read the log and react to it if something interesting comes up. However – and that’s important – the one writing the log doesn’t know about the readers/consumers or what they do. It’s up to the readers to look for certain events and react. Maybe the reacting of the consumer is time critical and must be performed as fast a possible, but that’s up to the consumer (not the producer or event).

      Let’s assume that we’ve an event called OrderCancelled. It’s consumed by two services. The first service informs our package center that the order should not be shipped. That’s time critical because if we package and ship an already cancelled order we lose money. Because this service (not the event!) is so critical it runs 24/7 on three different nodes. The second service refunds the money to the customer. That’s not time critical. It doesn’t matter if we book back the money now, in an hour or tomorrow morning. The bank transfer takes two days anyway.

      So it’s not up to the event if some reacting is time critical or not. It’s up to the consumers and the business case.

      Let’s stick with this example. Imagine we build another service based on the OrderCancelled event. This service sends an email to the customer asking why the order has been cancelled. Again, that’s not time critical. Of course, we shouldn’t send this email in six months, but it’s ok to send it in 5 minutes, in an hour or next week. However, the point is that the producer doesn’t know about the new consumer. The event is still the same but there’s a new service reading and reacting to it.

    • This is simply not correct. Not that things can’t be reasoned about or implemented this way, but simply that they shouldn’t be, because it undermines some of the most important benefits from an event-driven architecture. The vast amount of thought and best practices on this topic supports the author’s assertions.

      One of the main points of event-driven architecture is the decoupling it affords. By requiring a producer to know about its consumers couples components in precisely the way event-driven architecture is supposed to be used to decouple them.

      A producer of events is the author of a particular history. Things that have happened. Consumers own their own business logic and know what they need to listen for to be able to perform their function. So consumers should be able to discover what events are available in the system and subscribe to what they need to subscribe to, but producers should not care about who is listening to them.

      Yes, a consumer can’t listen for an event that is not being produced. But that doesn’t mean a producer is created for the consumer. It means that the business need for a particular consumer requires a new author of history to start broadcasting that history.

      And Commands can be rejected depending on the business rules and state of the receiver. In that way, it is accurate to say that they ‘should’ happen, because a rejection means that they didn’t happen, and the ramification is that the system needs to be able to know what to do when a command is rejected.