Lesson 2 / 25

Events, Commands, Queries and the Four Event Patterns

Distinguish events from commands and name the main event-driven patterns.

Words that change the design

A command is a request to do something, addressed to one handler, which may refuse it: PlaceOrder, ChargeCard. An event is a statement of a fact that already happened, named in the past tense and addressed to nobody in particular: OrderPlaced, PaymentFailed. A query asks for data without changing anything. Martin Fowler describes four patterns that people loosely call "event-driven". Event notification: a thin event says something happened, and consumers call back for details. Event-carried state transfer: the event includes the data consumers need, so they can keep a local copy and stop calling the source. Event sourcing: the sequence of events is the system of record, and current state is derived from it. CQRS: separate models for writing and reading. They combine well, but each has different costs, so name which one you mean in design discussions.

A command and the events it may cause

A command can be rejected; an event cannot be undone, only followed by another event.

// command: addressed to the Orders service, may fail validation
{ "type": "PlaceOrder", "customerId": "c-42", "items": [{ "sku": "pen", "qty": 2 }] }

// events: facts published after the decision
{ "type": "OrderPlaced", "orderId": "o-1001", "customerId": "c-42", "total": "40.00" }
{ "type": "OrderRejected", "customerId": "c-42", "reason": "OUT_OF_STOCK" }

Commands in disguise

An "event" named SendWelcomeEmail is really a command aimed at one consumer. Publish CustomerRegistered instead and let the email service decide to send a welcome email. That keeps the publisher ignorant of its consumers.

Quick check: Which of these is correctly named as an event?

  • ChargeCard
  • GetOrderStatus
  • ReserveStock
  • PaymentCaptured
Answer

PaymentCaptured — Events describe facts in the past tense; the others are commands or a query.