A request to change system state
A command is an imperative request to change the state of a system: confirm the order, cancel the booking, promote the user. It is named for the intent, phrased as an instruction, and it can be refused. A command is a request, not a guarantee, and that distinction is what makes it different from the event that follows a successful one. The system may validate it, reject it, or queue it; only when it succeeds does something become a fact.
The lineage starts with Bertrand Meyer's Command-Query Separation, formulated in the 1980s during his work on the Eiffel language and set out in Object-Oriented Software Construction. Meyer's rule: every method is either a command that changes state and returns nothing, or a query that returns data and changes nothing. Asking a question should never alter the answer.
Greg Young extended that principle from methods to whole models. Around 2010 he coined Command Query Responsibility Segregation, splitting the object that handles writes from the object that handles reads. Martin Fowler's CQRS (2011) gave the pattern its first careful write-up. As Young put it, CQRS keeps Meyer's definition of commands and queries and keeps them pure; the difference is that the system is divided into two objects, one for commands and one for queries.
Once commands became first-class objects rather than method calls, a vocabulary settled around them. A command is named in the imperative present tense (ConfirmOrder, not OrderConfirmed), it is addressed to a single handler, and it carries the data the handler needsNeedUserA user need, pain, desire, or constraintView reference → to decide. The handler validates against current state and either accepts the command, producing one or more events, or rejects it. This is the shape that event-sourced and message-driven systems adopted, and it is now the default mental model for the write side of CQRS.
A ticketing platform receives a ReserveSeat command carrying a seat id, a show id, and a customer id. The command reaches the handler for the relevant Booking aggregate. The handler checks the rules: the seat is free, the show is not sold out, the customer has no unpaid hold. If a rule fails, the command is rejected and the caller gets a refusal with a reason; nothing in the system changed.
When the rules pass, the handler does not mutate a row and move on. It records the decisionDecisionStrategyA recorded decision with context, rationale, and consequencesView reference → as a SeatReserved event, the durable fact that the reservation happened. A read modelRead ModelEngineeringA DDD read model (query projection)View reference → later consumes that event to update the seat map shoppers see. The command expressed an intent that could have been denied; the event records that the intent succeeded. Tracing a bugBugProduct SpecificationA defect or unexpected behaviourView reference → becomes a matter of asking which command was sent and which events it produced.
ConfirmOrder may fail; OrderConfirmed already happened.In the Unified Product Graph, a command is an engineering-region entity that models an intent to change state. The AggregatehandlesCommandhierarchy edge connects it to the aggregate that decides its fate, and aggregate_handles_commandCommandproducesDomain Eventcausal records the facts a successful command emits. The loop closes through command_produces_domain_eventDomain EventtriggersCommandcausal, where one event prompts the next command, which is how event-driven workflows chain together. Representing commands as nodes makes the write side legible: you can read off every state change a system can be asked to make, which aggregate guards each one, and what becomes true when it succeeds.domain_event_triggers_command
Type-specific fields on BaseNode
command_handlerstringProcessing handler
validation_rulesstringPre-execution validation rules
idstringrequiredUnique identifier (UUID)
typeNodeTyperequiredDiscriminator for the entity type
titlestringrequiredDisplay name
descriptionstringOptional detailed description
statusstringLifecycle status
tagsstring[]Freeform tags for filtering
3 edge types connected to this entity.
aggregate_handles_commandcommand_produces_domain_eventdomain_event_triggers_command