Events, commands and queries
Every message between services is one of three kinds, and the kind decides how it is named, who receives it and what the sender may expect. An event states something that already happened, a command asks one service to do something, and a query asks one service for data.
| Kind | Named as | Goes to | Can the receiver refuse? | Example |
|---|---|---|---|---|
| Event | Past tense | Zero, one or many subscribers | No, it already happened | OrderPlaced |
| Command | Imperative | One owner | Yes, it can fail or be rejected | ReserveStock |
| Query | A question | One owner | It can return nothing or an error | GetOrderStatus |
Events
An event is a fact. PaymentReceived cannot be refused by the services that hear it, because the payment has already been received. The producer does not expect any particular reaction, and there can be many subscribers or none. Microsoft’s guide puts it as a message “that a producer raises to announce that something happened”, with no expectation of a specific action.
Commands
A command asks for work: ReserveStock. It goes to the one service that owns that work, and the owner can reject it, for example because the stock is not there. The sender may wait for the outcome and decide what to do next. Commands have stricter delivery needs than events, because a lost command can fail the whole business transaction, and processing one twice can cause a double charge.
Queries
A query changes nothing. It asks for data and expects an answer, so it normally travels over a direct request, such as a call to an APIRESTful API designNaming, methods, status codes, formats and security for an API that is easy to use.Opens in a new tab, not over a broker. Whether to query another service at all is covered in asking another service for dataAsking another service for dataFour ways to get data a service does not own, and what each costs.Opens in a new tab.
The catch
A command dressed as an event hides a dependency. If Orders publishes OrderPlaced but the design only works when Payments charges the card, Orders is relying on a specific service to act. Martin Fowler calls this a “passive-aggressive command”. When the sender needs a specific service to act, send a command to that service and name it as one. Publish an event only when the producer would be correct whether or not anyone reacts.
Sources
- Asynchronous Messaging Options, Azure Architecture Center, Microsoft Learn · accessed June 12, 2026
- What do you mean by Event-Driven?, martinfowler.com · accessed June 12, 2026