Tom
Typed on a mobile
for the occiasional crud-like operation within a bounded context for
which cqrs is otherwise sensible, I see no disadvantage. The additional
overhead is not that high, somtimes it is far easier to reuse the
infrastructure.
With event sourcing, there usually is one "XYZUpdated" event and one or
multiple projections making use of the event. Within the domain itself,
there simply is a method emitting the appropriate event.
You can even handle such commands in a command handler and not have a
domain model involved at all.
Even for some purely crud style use cases, the audit log may be of
value. Think e.g. of changing the account # of a payee. Maybe the
account # is read of the read model in the end, so you will never even
have that field in the domain. But having a record of who changed it is
crucial.
Cheers
Phil
If you are doing plain old CRUD, do you even need a domain model? You can still do CQRS/ES, but just have your command-handlers implemented like transaction-script pattern and generate events directly. If we have no behaviour, there is no need for AR’s as far as I can see.
You can still do CQRS/ES, but just have your command-handlers implemented like transaction-script pattern and generate events directly.
I would still have a Repository layer that knew how to publish/store events. I would just generate the events directly in my command handlers then pass them to the repository, instead of the usual approach of having the command handler call out to the domain model to gen events. E.g. :
public void HandleCommand(DeleteCustomerCommand cmd) {
_repository.PublishEvent(new CustomerDeletedEvent(cmd.CustomerId));
}
Cheers,
Dylan
From: ddd...@googlegroups.com [mailto:ddd...@googlegroups.com]
On Behalf Of Werner Clausen
Sent: Wednesday, December 14, 2011 5:44 AM
To: ddd...@googlegroups.com
Subject: Re: [DDD/CQRS] Disadvantages of having CRUD as part of your CQRS-ES?
@Dylan && @Nuno,
some more thoughts on that.
Conceptually, every part* of the system that uses a different
architecture (e.g. domain model vs pure-crud vs. transaction script)
should be using a separate event store.
The implementation may very well be a single store, but e.g. an
aggregate should never request an event not originating from it. This
does not preclude responding to the published event within an event
handler, I am just talking about access to the storage. So you do not
need to restrict access to the event store to the domain model, but to
restrict access to events to those parts of your code from which the
events originate. With the exception of projections/denormalizers, which
obviously need to have access to all events.
For the CRUD part, you do not really need to load up any events. Loading
up previous events means conditional reaction depending on state. Such
rules should be implemented in the domain model. For the cruddy
operations, I limit myself to "update" and "mask/delete" events that are
idempotent and - well CRUDdy. As soon as something requires previous
state, I model it as an entity/aggregate to avoid the
transaction-script/anemic domain model path.
There is one exception however: for major version upgrades that require
generation of "correction" events, I use a lot of transaction scripts.
In such situations usually the alyout of aggregates change, and
therefore it makes sense to momentarily lift the consistency boundary
when transitioning from one domain model to another.
Cheers Phil
* (These parts are often called "bounded context" here, but I feel that
the term has actually been overloaded with at least two seperate meanings.)
You really want to have that granularity.
UpdateCustomerAddress(customerId, address)
and
AddressWasChanged as a corresponding event is perfectly valid.
Partial updates was not the point I tried to make, rather conditional
updates.
You don't want to have a condition refering to current state in the CRUD
command handler (e.g. "Address is changed only if the customer is still
active").
As soon as you have any kind of logic, include that in your domain
model. In other words: Update and Deletes must not fail and must be
idemponent.
Otherwise, it's no longer a crUd operation.
Cheers
Phil