The use of the commands that do not require aggregate state (eg RenameInventoryItem)

187 views
Skip to first unread message

xiety

unread,
Jan 19, 2017, 5:37:01 AM1/19/17
to DDD/CQRS
Why there is command RenameInventoryItem in SimpleCQRS? And why does it require aggregate loading? What invariant does it protect in this case? Why can't we directly emit event InventoryItemRenamed without aggregate involved?

Alexander Langer

unread,
Jan 19, 2017, 5:57:35 AM1/19/17
to ddd...@googlegroups.com
Who protects the invariant? The aggregate or the command handler?

On 19/01/2017 11:37, xiety wrote:
> Why there is command RenameInventoryItem inSimpleCQRS
> <https://github.com/gregoryyoung/m-r>? And why does it require aggregate
> loading? What invariant does it protect in this case? Why can't we
> directly emit event InventoryItemRenamed without aggregate involved?
>
> --
> You received this message because you are subscribed to the Google
> Groups "DDD/CQRS" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to dddcqrs+u...@googlegroups.com
> <mailto:dddcqrs+u...@googlegroups.com>.
> Visit this group at https://groups.google.com/group/dddcqrs.
> For more options, visit https://groups.google.com/d/optout.

Alexander Langer

unread,
Jan 19, 2017, 5:58:20 AM1/19/17
to ddd...@googlegroups.com
meant to write "a future invariant".

xiety

unread,
Jan 19, 2017, 6:24:21 AM1/19/17
to DDD/CQRS
Aggregates are intended to protect invariants. What future invariant are you talking about? I cannot see any invariants into which inventory's Name is involved. So Name does not belong to InventoryItem aggregate for me.

Boris Guéry

unread,
Jan 19, 2017, 6:44:56 AM1/19/17
to ddd...@googlegroups.com
This project is for educational purpose only, in real life there may be reasons to protect some invariant when Renaming an Item (maybe only allow renaming when an Item is not publicly available or whatever rule fits the domain).

However, I sometimes does not involve any aggregate if it is not required, but it doesn't necessarily prevent me from having a `Command`.

The Event would be emitted directly in the `CommandHandler` to the `EventStore`.

--
Boris Guéry - IT Consultant / Software Architect

twitter: @borisguery
mobile:  +33686830312
skype:   borisguery

On Thu, Jan 19, 2017 at 11:37 AM, xiety <xiet...@gmail.com> wrote:
Why there is command RenameInventoryItem in SimpleCQRS? And why does it require aggregate loading? What invariant does it protect in this case? Why can't we directly emit event InventoryItemRenamed without aggregate involved?

--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+unsubscribe@googlegroups.com.

Greg Young

unread,
Jan 19, 2017, 6:46:33 AM1/19/17
to ddd...@googlegroups.com
Its a toy app. Though in a real one if I already had an aggregate
unless I had some performance constraints I may still do it that way
as it fits. Also remember that in many models your aggregate is
already in memory.
> --
> You received this message because you are subscribed to the Google Groups
> "DDD/CQRS" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to dddcqrs+u...@googlegroups.com.
> Visit this group at https://groups.google.com/group/dddcqrs.
> For more options, visit https://groups.google.com/d/optout.



--
Studying for the Turing test

xiety

unread,
Jan 19, 2017, 8:24:25 AM1/19/17
to DDD/CQRS
But why we need to create a command? It cannot be discarded by some invariant. If it passes the read-model validation, it can be published directly to event store, without command, command handler and aggregate. So it looks like an event from the beginning.

Greg Young

unread,
Jan 19, 2017, 8:26:04 AM1/19/17
to ddd...@googlegroups.com
because when you have all of 5 behaviours and performance requirements
of 1 message per second your "optimizations" are actually
obfusications.

Chris Richardson

unread,
Jan 19, 2017, 9:49:00 AM1/19/17
to ddd...@googlegroups.com
What about verifying that the inventory item exists before emitting the event?

-- 
Learn microservices - http://learnmicroservices.io
Microservices application platform http://eventuate.io


On Thu, Jan 19, 2017 at 2:37 AM, xiety <xiet...@gmail.com> wrote:
Why there is command RenameInventoryItem in SimpleCQRS? And why does it require aggregate loading? What invariant does it protect in this case? Why can't we directly emit event InventoryItemRenamed without aggregate involved?

--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+unsubscribe@googlegroups.com.

Greg Young

unread,
Jan 19, 2017, 9:50:25 AM1/19/17
to ddd...@googlegroups.com
eh you can do that with expectedversion ;-)

On Thu, Jan 19, 2017 at 2:48 PM, Chris Richardson
<ch...@chrisrichardson.net> wrote:
> What about verifying that the inventory item exists before emitting the
> event?
>
> --
> Learn microservices - http://learnmicroservices.io
> Microservices application platform http://eventuate.io
>
>
> On Thu, Jan 19, 2017 at 2:37 AM, xiety <xiet...@gmail.com> wrote:
>>
>> Why there is command RenameInventoryItem in SimpleCQRS? And why does it
>> require aggregate loading? What invariant does it protect in this case? Why
>> can't we directly emit event InventoryItemRenamed without aggregate
>> involved?
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "DDD/CQRS" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to dddcqrs+u...@googlegroups.com.
>> Visit this group at https://groups.google.com/group/dddcqrs.
>> For more options, visit https://groups.google.com/d/optout.
>
>
>
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "DDD/CQRS" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to dddcqrs+u...@googlegroups.com.
> Visit this group at https://groups.google.com/group/dddcqrs.
> For more options, visit https://groups.google.com/d/optout.



João Bragança

unread,
Jan 19, 2017, 10:02:03 AM1/19/17
to ddd...@googlegroups.com
Also, consider that while you may not need it now there is nothing that says it won't be required in the future, e.g. a new rule that says deactivated items can't be renamed.

xiety

unread,
Jan 20, 2017, 2:50:26 AM1/20/17
to DDD/CQRS, joao...@braganca.name
In this toy example InventoryItem aggregate seemed like it was designed around a data of an inventory item, and not around some sort of invariant. If in the future there will be some invariant involving Name, we will consider to create some new aggregate for it, or merge it with existing aggregate, if it embraces it's invariants. But why do we need to predict the future in this case? When event will not be enough, we will create command for that.

Or are you trying to say, that an "existence of an item" is the invariant to check when we renaming? It means that all future data fields will be included to this sole aggregate of an item? So aggregate is created around the data and not around some business constrains?

But I think that read-model validation will be enough in many validation checks here. Including the existence check and item is publicly available check.

The only reason I see to create an useless command, is to make all interactions with the domain model and tests similar.


On Thursday, January 19, 2017 at 5:02:03 PM UTC+2, João Bragança wrote:
Also, consider that while you may not need it now there is nothing that says it won't be required in the future, e.g. a new rule that says deactivated items can't be renamed.
On Thu, Jan 19, 2017 at 3:48 PM, Chris Richardson <ch...@chrisrichardson.net> wrote:
What about verifying that the inventory item exists before emitting the event?
-- 
Learn microservices - http://learnmicroservices.io
Microservices application platform http://eventuate.io


On Thu, Jan 19, 2017 at 2:37 AM, xiety <xiet...@gmail.com> wrote:
Why there is command RenameInventoryItem in SimpleCQRS? And why does it require aggregate loading? What invariant does it protect in this case? Why can't we directly emit event InventoryItemRenamed without aggregate involved?

--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+u...@googlegroups.com.

Visit this group at https://groups.google.com/group/dddcqrs.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+u...@googlegroups.com.

Visit this group at https://groups.google.com/group/dddcqrs.
For more options, visit https://groups.google.com/d/optout.

Phil Sandler

unread,
Jan 20, 2017, 9:58:29 AM1/20/17
to DDD/CQRS
Sorry to jump in with a follow up question here . . .

Assuming you decide it is not needed on the aggregate, you would still add it to the stream/store with the same streamId as the aggregate?  You would just add it directly to the store instead of via the aggregate?

Greg Young

unread,
Jan 20, 2017, 10:06:31 AM1/20/17
to ddd...@googlegroups.com
I normally for a stream would either have an aggregate or not.

Phil Sandler

unread,
Jan 20, 2017, 10:15:33 AM1/20/17
to ddd...@googlegroups.com
By this you mean: if you have an aggregate, all related changes get processed through the aggregate, and all events get emitted from the aggregate?

This is the way we've been doing it, but have had internal debate about whether it's "correct" to have a few stray state changes that don't have to be validated against (or change) aggregate state.


Thanks,

Phil


> Visit this group at https://groups.google.com/group/dddcqrs.
> For more options, visit https://groups.google.com/d/optout.



--
Studying for the Turing test

--
You received this message because you are subscribed to a topic in the Google Groups "DDD/CQRS" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/dddcqrs/K7JRYBuZce8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to dddcqrs+unsubscribe@googlegroups.com.

Greg Young

unread,
Jan 20, 2017, 10:18:31 AM1/20/17
to ddd...@googlegroups.com
Have never had a need to separate them. Often I will write without an
aggregate often I will write with. If I have one I tend to follow it.

Same thing with functional code, if I load state I load state for all
on the stream.
>> You received this message because you are subscribed to a topic in the
>> Google Groups "DDD/CQRS" group.
>> To unsubscribe from this topic, visit
>> https://groups.google.com/d/topic/dddcqrs/K7JRYBuZce8/unsubscribe.
>> To unsubscribe from this group and all its topics, send an email to

Thomas Schanko

unread,
Feb 23, 2017, 8:05:56 PM2/23/17
to DDD/CQRS, joao...@braganca.name
Long story short: Assuming your read models are eventually consistent, you'll simply end up with a non deterministic system. Stating that read-model validation might be good enough to add an event to a stream sounds like a pretty pragmatic approach in the first place. But who is the source of the InventoryItemRenamed event in that case? The UI? Given that you already have an aggregate in place feeding the stream, you're effectively introducing a second source of truth. Even not being into fortune-telling too much, this looks like trouble ahead. Identity and lifespan are what entities - and hence, aggregates - are all about. So, to me, 'existence of a thing in time'  looks like a valid invariant to care about in the context of renaming it. Maybe only due to my philosophical background...
It's to be or not to be, to have an aggregate or to go without...

Rickard Öberg

unread,
Feb 23, 2017, 9:44:43 PM2/23/17
to ddd...@googlegroups.com, joao...@braganca.name
The way I deal with this to have a separate bounded context using the same identity. In our case, we have a video aggregate that gets created and it has its own code and snapshot state and what not, relevant for validating commands in that space. Then, we use the same identity to allow comments on a video, but that does not require the same state in the snapshot for validating commands. So we use different aggregate code, different snapshot state, but same identity, and then apply commands and get events for that, which end up in the same read model. This gets around the issue of different commands requiring different snapshot state to handle invariants.

Sent from my iPad
Reply all
Reply to author
Forward
0 new messages