Axon is heavily based on the principles of Domain-Driven Design (DDD) and Command Query Responsibility Segregation. While a full explanation of these concepts is beyond the scope and intent of this reference guide, we do want to provide a summary of the most important concepts in the context of an Axon application.
Strategic concepts are relatively high-level concepts that influence a system's design on a architectural level. It provides the concepts to design boundaries of components and the interaction between them. While they don't directly impact the design of an individual Axon application, the boundaries of such applications are often influenced by these concepts.
This definition may appear vague, but it does capture the essence very well. The domain is basically the environment in which you build your software. This environment consists of laws, best practices, expectations, traditions, etc, which define what is important and what is not.
Domains can be very big and different areas within a domain might have different influences. For example, in the domain of banking, there is a clear difference between consumer banking, corporate banking and wealth management.
There are numerous techniques that can help you to discover a domain. Event Storming is a particularly interesting one. It is a workshop format for quickly exploring complex business domains.
In other words, a model captures what's important and helpful to us in solving a specific problem within our domain. This definition in itself suggests that an application should consist of more than one model, as each problem has a different ideal model to address it.
See Tactical Concepts for more information about some of the building blocks of a Model in Axon based applications.
Keep the model strictly consistent within these bounds, but don’t be distracted or confused by issues outside it.
In Axon based application, the context defines the boundary in which Events carry value. Some events may be valuable only in the context in which they are published, while others may be valuable even outside. The broader the scope in which an event (or any message, in that respect) is published, the more components end up coupling to the sender.
To build a model, DDD (and CQRS to some extent as well) provide a number of useful building blocks. Below are a few building blocks that are important in the context of Axon based applications.
An Aggregate is an entity or group of entities that is always kept in a consistent state (within a single ACID transaction). The Aggregate Root is the entity within the aggregate that is responsible for maintaining this consistent state. This makes the aggregate the prime building block for implementing a command model in any CQRS based application.
In CQRS based applications, Aggregates are very explicitly present in the Command Model, as that is where change is initiated. However, Query Models / Projections are also built up of Aggregates. Generally, however, aggregates in Query Models are much more straightforward, as state invariants are generally less strict in those models.
Not every command is able to completely execute in a single atomic transaction. A very common example that pops up quite often as an argument for transactions is the money transfer. It is often believed that an atomic and consistent transaction is absolutely required to transfer money from one account to another. Well, it is not. On the contrary, it is quite impossible to do. What if money is transferred from an account on bank A (instance A of aggregate BankAccount), to another account on bank B (instance B of aggregate BankAccount)? Does bank A acquire a lock in bank B's database? If the transfer is in progress, is it strange that bank A has deducted the amount, but bank B hasn't deposited it yet? Not really, it's "underway". On the other hand, if something goes wrong while depositing the money on bank B's account, bank A's customer would want his money back. So we do expect some form of consistency, eventually. Another example could be GiftCardPaymentSaga which would start once the ordre is placed (OrderPlacedEvent). It will make sure that once the gift card is successfully redeemed (CardRedeemedEvent), an order is confirmed (ConfirmGiftCardPaymentCommand) on the other side.
While ACID transactions are not necessary or even impossible in some cases, some form of transaction management is still required. Typically, these transactions are referred to as BASE transactions: Basically Available, Soft state, Eventual consistency. Contrary to ACID, BASE transactions cannot be easily rolled back. To roll back, compensating actions need to be taken to revert anything that has occurred as part of the transaction. In the gift card example, a redeem failure of GiftCard, will reject the Order payment.
In CQRS, Sagas can be used to manage these BASE transactions. They respond to events and may dispatch commands, invoke external applications, etc. In the context of Domain-Driven Design, it is common for Sagas to be used as coordination mechanism between different aggregates (or aggregate instances) in order to eventually achieve consistency.
In CQRS, View Models (also known as Projections or Query Models) are used to efficiently expose information about the application's state. Unlike Command Models, view models focus on data, rather than behavior. View models are generally modeled to accommodate information needs of a specific audience. These models should clearly express the intended audience of the model, to prevent 'distraction' and scope creep, which ultimately leads to loss of maintainability and even performance.