Separating the commands from the queries
Another key principle I really like is CQS (Command Query Separation). It took me a while to see its power, but since that moment I have found that it works quite well and actually simplifies a lot, although it requires a mind shift and needs you to think a bit different. You also have to take it into account up front the design process. Basically it means that you separate the commands from the queries, as they are completely different in nature. Executing commands involves domain logic and requires the fact that you should express the business intend of your system (which goes hand in hand with a task oriented user interface); while the query side just needs to retrieve data in a specific format.
Let’s take a simple example to describe the difference.
Imagine a web application that shows personal information about a user and offers the possibility to change it. Displaying personal information of a user is straightforward: you want to retrieve the data that is shown on the page, nothing more, and nothing less; and there’s no need to execute domain logic because the query does not have any side effects: it’s just getting the data in a specific format. Changing data however is more complex – and you probably don’t want to have an operation like ModifyPersonalInformation, because this is merely a CRUD operation that doesn’t express any business intend. If we want to change an email address for example, we don’t want to pass al the personal information; but only the new email address and probably the password to be able to validate the request. So we better create a ChangeEmailAddress command, that contains only the needed information so that the command can be executed correctly. By doing this, we also very explicitly make clear that this will change email address which involves some domain validation and logic, which will cause side effects.
As a result, the query side can be kept simple, as its only purpose is to somehow get the data from one or more data sources, and maybe transform and aggregate it into a format usable by the consumer. The command side however can have a fully-fledged domain model with complex logic, validation, transaction management, workflow and everything needed to process commands.
Both query and command side can operate on the same data source, or they could each have their own data source: in this case the query side would work with a data source optimized for reading data (which can be a relational database with dedicated views or maybe a NOSQL system), while the command side would work with a data source optimized for writing data (like a relational database). Note that if you use separate data sources, you also introduce the additional need of keeping the read data source side in sync with the write data source; so it’s an important design decision that causes additional overhead.
Not so strict CQS
As discussed above, the command side is responsible for processing commands requested by a consumer. A command is purely a data container that holds enough information to be able to execute the command. The actual execution is handled by its designated command hander, which contains all the logic needed for the actual execution of the command.
If you look at CQS in a strict way, a command should have only the responsibility of executing the command, and not return data. Following this pattern has fundamental consequences, and because I’m not a purist, for now I’m going to allow our commands to return simple data (like an id or a status), and they can also throw faults in case something goes wrong. Sure, this violates the CQS principle, but the main goal now is to have the commands use the underlying domain model while the queries use the underlying database directly.
Next time I will start implementing a concrete example that demonstrates the architecture and principles.