Deterministic guids for events/commands

Hello,

This maybe a stupid question but I’m pretty new to event sourcing and cqrs but as part of my R&D for my new project I have a question regarding deterministic ID’s for my events and commands.

Up until now I have been using Guid.NewGuid() in C# to just generate random id’s for the events/commands.

After recent reading though it seems that to cover event idempotence using GES I would need to use a deterministic id as well as the expected version.

I already have the expected version implemented and that is working well; with the event ID I have replaced Guid.NewGuid() with this inside my eventstore repo :-

private Guid ToDeterministic(IEvent e)
{
return GuidUtility.Create(Guids.SystemNamespace, $"{typeof(TAggregate).Name}-{e.AggregateId}-{e.Version}");
}

``

The guid utility class is from here: https://code.logos.com/blog/2011/04/generating_a_deterministic_guid.html

Is this the correct way to implement this or have I miss-understood something?

Could/should the guid namespace be the system or should it be more granular e.g, sub-domain/aggregate?

I’m assuming this would apply to commands also?

Thanks in advance,

Rick.

You only need to use deterministic guids if you want to leverage ES's
idempotency to make your API idempotent (and not have clients generate
uuids).

Okay, I’m still a bit confused so apologies as I’m still learning.

So would a new guid work okay with expected version when saving events?

So when it comes to process managers/sagas/etc… making the commands idempotent for these processes would mean making the managers that handle these commands track the commands ‘seen’ internally? Like a simple list of command ids.

I have a potential for commands to be resent because of failures and I don’t want them to be handled again :slight_smile:

Because retrying an event should not generate a new id. Your case you
describe of the command is where deterministic guids (or having client
create the id) comes into play (eg you want to use es's idempotency to
make your commands idempotent).

Hmm is using ES not the correct way to handle command idempotency, should I be doing it another way like saving the processed commands somewhere?

When you say client are you referring to the caller of my web API; like some JS frontend or do you mean the actual API itself that dispatches the commands or something else?

Im struggling to find any decent examples of how this should be done, ones that I find are very trivial and dont explain a great deal. Would following your online video course help with this?

I am referring to the client sending the command. In order to get
idempotency out there a few things to think about.

1) ability to identify the event as being the same event
2) do you have other side effects?

If #2 you will need to make those idempotent as well. If only #1 there
are two common ways of getting the same id every time. The first is
you can put the uuid on the command and use it when creating the
event. The second is to use a deterministic guid generator (off of say
the command's message id). Both mechanisms will generate the same id
for the event if rerun.

Greg

Okay cool I think I’m with you.

So given this scenario for example where a command is sent { commandId: 123, userid: 456, name: “rick” }; this would create an event in the store for stream User-456 and the event {eventid: 123, userid: 456, name: “rick”}

Also i’m guessing if the command was to raise two events within the aggregate then you would have to use the deterministic approach to create the event IDs (or at least the additional event ids)?

Thanks for your patience!