· 3 min read

How to Choose and Name Commands for Event Sourcing or CQRS

Explore two approaches for creating and naming commands in command-based systems, balancing domain logic with structured formats.

Explore two approaches for creating and naming commands in command-based systems, balancing domain logic with structured formats.

In a codebase made of many service classes, methods are typically grouped by resource, making them easy to find. Eg, all methods related to User would be in UserService. However, in a command-based systems, like event sourcing, we deal with many small command classes, which can complicate naming and organization.

  1. How do we decide which commands to create?
  2. How do we name commands for easy discovery?
  3. How do we ensure consistency in naming?
  4. How do we balance clarity for both developers and business users?

The following post attempts to answer these questions. This is not an exhaustive list. If you know something, do post a comment below.

Approaches for Creating and Naming Commands

1. Creating Commands Based on Domain Language & Use Case

You convert all the use cases from your business requirements / PRD into a command.

For example, if you are building a banking application, you may have the following use cases.

Business Use CaseDomain Specific Command
Create Savings AccountCreateSavingsAccount
Close Savings AccountCloseSavingsAccount
Add DepositAddDeposit
Transfer FundsTransferFunds
Think of each atomic operation in the business use-case

Pros & Cons

Can we decide what commands to create?

  • 👍 Yes, commands map directly to business use cases.

How do we decide what the name of the command is?

  • 👎 It may be challenging to name commands if the requirements aren’t precise.
  • 👍 With precise requirements, naming commands becomes easier.

Would you understand what the command is doing?

  • 👎 From the developer’s perspective: No.
  • 👍 From a business perspective: Yes.

Can you find the commands easily?

  • 👎 It can be challenging to find existing commands as the codebase grows without a consistent naming format.
#MoreYouKnow: Know the difference between a command and an event: A command is something we want to perform, while an event is something that has happened. For example, SignupUser is a command, and after the user is signed up, you might have UserSignedUpEvent.

2. Creating Commands in a Structured Format

Here’s a format I often use which I described in my blog: Event Sourcing - Good Naming Convention:

{Create/Update/Delete}{Entity}{FieldName}
Business Use CaseCommand
Create Savings AccountCreateSavingsAccount
Close Savings AccountUpdateCloseSavingsAccount
Add DepositUpdateAccountAddDeposit
TransferUpdateAccountTransferFund

Pros & Cons

Can we decide what commands to create?

  • 👍 You can still do a 1:1 mapping with business use cases.
  • 👎 Since we are not following business language, we may end up creating more commands than necessary.

How do we decide on the command name?

  • 👍 This format simplifies the process of naming new commands.
  • 👎 It can be challenging to name non-entity actions like “Sending an email.” You might end up with names like SendEmailAction, but SendEmail is simpler and more domain-specific.

Would you understand what the command is doing?

  • 👍 From a developer’s perspective: Yes, command names are more precise, e.g., UpdateMovieReleaseDate.
  • 👎 From a business perspective: No, names may sound robotic like UpdateCloseSavingsAccount.

Can you find the commands easily?

  • 👍 Easier to find existing commands as the format narrows down your search to create, update, or delete actions.
  • 👎 As the codebase grows, finding names can still be challenging without consistency.

Ending

Above, I described two approaches for deciding what commands to create and what it’s name should be.

  • Domain-specific commands: Harder to name but more aligned with business language, offering greater clarity in some contexts
  • Format-based commands: Consistent and easier to enforce using tools like ArchUnit.

There’s no one-size-fits-all solution. Both approaches have pros and cons. Personally here’s what I do

  • To know what command to create: Rely on domain use case.
  • For naming the command: Rely on a consistent format still use as much domain specific language as possible.
    • Instead of SignupUser, I’d name it CreateUser, even if a POST /signup is triggering it.
**General Tip**: Commands always follow a similar pattern to service methods, with a {Verb}{Noun} format. So, SendEmailCommand is better than EmailSendCommand, which sounds more like an event.

What I presented is no way exhaustive. If you know a better approach do let me know in the comments below.

Resources


Back to Blog