Oh the irony.
The DDD community advocates for unambiguous language. And yet even our own terms are heavily overloaded. Whether it’s on stackoverflow like here or on the DDD/CQRS google group like here.
So, just to be clear …
… a CQRS command is not the same as the Gang Of Four Command Pattern.
But what are the differences and how best to use them? This is what I’ll cover in this post.
The Command Pattern – Gang of Four Style
The GOF Command Pattern falls under the Behavioural grouping. This group of patterns describes mechanisms of communication between classes and objects. In this case, it is an object used to express a request. It holds the necessary information and has a common mechanism to execute. The interface looks like this:
Here is an example of the command design pattern in c#:
public interface ICommand { void Execute(); }
What’s A Good Use Case For This Pattern?
Matt Honeycutt suggests an elegant use case. In his course on plurasight “Build Your Own Application Framework on ASP.Net MVC 5” he uses the command pattern rather ingeniously.
Let me explain…
How many times have you needed certain tasks to run at certain common times in your application? For example, some setup code at the start of your application. Maybe you need something done after each request or on error. When it’s just one thing most of us just code it up. But what happens when we need a series of things to run?
Enter the GOF command pattern.
Rather than just create an interface called ICommand which in a CQRS app can get confusing. Matt suggests in his course naming the command interface definitions after when they need to be run (Note – Matt refers to them as Tasks). For example:
- IRunAfterEachRequest
- IRunAtStartUp
- IRunOnError
For more ideas see his GitHub repo at: https://github.com/MattHoneycutt/Fail-Tracker/tree/master/FailTracker.Web/Infrastructure/Tasks
I have used this approach in my applications. Just like the GOF command, it has a single void Execute function. At this point we can use our DI framework of choice to get all startup commands. Then during application start execute each one.
What does this mean for you?
It is a simple way to ensure each startup task is handled in a uniform way. It is very easy to add new tasks and each class has only one reason to change.
In this sample from a Global.asax.cx file, I’ve used a service locator pattern (some see this as anti-pattern). I think it’s an elegant way to handle this type of task.
public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); // Run all the startup tasks foreach (var startUpTask in ServiceLocator.Kernel.GetAll<IRunAtStartUp>()) { startUpTask.Execute(); } } }
In case you are curious, just register each startup class in the inject kernal like so:
kernel.Bind<IRunAtStartUp>().To<MessageSecurity>(); kernel.Bind<IRunAtStartUp>().To<ConflictResolver>();
So What is a CQRS Command?
It differs in that a CQRS command is a message. It represents an action. It cannot be executed. Rather we route it to a handler. Messages in a CQRS system are also immutable. This immutability and the fact we route commands gives this pattern it’s power and flexibility.
What else can we do with them?
We can send a command over the wire. We can queue them and even re-route them. Commands are generally made up of simple types. As such they are easy to serialise and log. There are no dependencies to worry about.
What’s more …
Commands represent actions which you have identified in the domain. They form part of the lexicon or ubiquitous language. Naming a command is a careful process. It should be intention revealing. It should also be understandable by the domain experts.
Think about it…
The beauty of using well named commands is that you create a kind of domain specific language (DSL). If you get it right, you gain a deep understanding of the domain. Which in turn helps you to architect a better system.
For more background to naming commands check out DDD – Special scenarios, part 2“.
What Does a Typical CQRS Command Look Like?
Every application domain requires differing shaped commands. However, certain fields come up fairly often. Here is an example of a typical CQRS command.
public class ExampleCommand : Command { public readonly Guid AggregateId; public readonly int Version; public readonly Guid UserId; public ExampleCommand(Guid aggregateId, int version, Guid userId, Guid processId) : base(processId) { AggregateId = aggregateId; Version = version; UserId = userId; } }
It inherits from Command and Command Inherits from Message.
Sounds complicated?
Well not really. Message is just a placeholder interface. It’s used out of convenience to group all messages together. A command on the other hand will often have some common elements.
In my experience these are …
Aggregate Id: A command runs against a specific aggregate. We identify the aggregate via its unique id.
Version: The command will usually carry a version or timestamp. This ensures that it is executed against the aggregate when it is in the correct state. You wouldn’t for example want to get an enable or disable command mixed up. I tend to use a simple integer. I ensure any events I create off the back of the command carry that version. This enables you to detect concurrency conflicts.
Process/Correlation Id: If you are using an Event Sourcing approach you will want to include a correlation id. This allows you to trace events back to a specific starting command. It becomes particularly important when you have process managers or Saga’s. They will trigger further actions from an initial starting command. Without some form of correlation id it can become very difficult to trace the ripples caused by the initial command.
User Id: Again, depending on the domain, a command will often carry a user id. This is the user id of the person issuing the command. It is useful to make a convention that every command carries a userid. This makes logging and security much easier to implement.
One word of caution with user id’s. This may just be me. But if you do have a user id on a command as a convention, make sure you stick to it’s meaning. I got myself into all sorts of confusion when I built a system that handled user accounts. I assumed in some cases the user id referred to the account I was changing. It didn’t, but rather it was the id of the issuer.
Conclusion
From this write up, I think it’s clear that a GOF command is a different beast to a CQRS command. But it does highlight a broader issue. Be careful when using DDD not to assume you know what a particular term means. Do read up about it. Get a copy of the ‘Blue Book’ and read the threads on the lively DDD/CQRS google group. There is always more to learn!
Don’t let terminology bite you in the ass 🙂
In the case of a Process Manager or Saga triggering the command, would you use it’s ID to the userId property?
Good question. It can sometimes make sense to have a dedicated ‘system id’. That way you can differentiate between user and system initiated actions. I would explicitly set an id in this case rather than use Guid.Empty for example. This is because Guid.Empty is the default value which could get set if a non-logged in user tries to issue a command (if that’s even possible in your system).
An alternative is to carry forward the id of the initiating user. However, I prefer the first option as you can always find out the initiating user from the process id.
So maybe it’s better to name this as `commander`, with type: and id: properties? Type being the class string representation and id the GUID. This is more expressive than ‘userId’, as you have pointed out can be a problem since it has multiple meanings in different contexts
[…] Is a CQRS Command = GOF Command? (Daniel) […]