Commands vs Events

In the context of Command Query Responsibility Separation (CQRS) and Event Sourcing it's not immediately clear to me the difference between commands and events. The simplest understanding I have of it is the following statement.

Commands produce events.

Let's examine that a bit closer, if only for the reason that a command and an event could look very similar in code.

RegisterUser {  
  Email
}

RegisteredUser {  
  Email
}

The main difference is what they're used for—their intent.

Events represent the past.

An event is something that has already happened in the past, so by convention we name these in past tense—RegisteredUser. The event represents the the past and will always have happened no matter what. It never changes once it's happened—it's immutable.

Commands represent a possible future!

A command intends to produce a change... an event... but it's role is placed before the event happens (or doesn't!). For that purpose they're named with a commanding verb—RegisterUser.

The role of the command is to determine whether the event can happen based on what we currently know. Imagine we have the business rule that two users can't have the same email—it's then up to the command to validate and throw an error if we violate the business rule.

In the example "code", both command and event look like data, but it makes more sense that the command is a function. That way it can contain the business logic for the email validation.

registerUser(Email) -> Boolean

RegisteredUser {  
  Email
}

You've probably noticed that the function registerUser() returns a boolean. This is intentional and comes from CQRS—the command determines whether it's possible to register a user. If it's possible the next step is to commit the event to the event log... but I'll keep that for a future post.


Greg Young's keynote on Event Sourcing