Pergunta

I'm wondering exactly what logic should be contained when applying an event to a state while replaying events using some event sourcing solution.

Specifically, I'm wondering about validation, say I've got entity which can be in one of the following status:

  • Logged
  • Active
  • Close
  • Cancelled

and the progress needs to be Logged->Active->Close or Logged->Active->Cancelled, we cannot jump from Logged to Close directly for example.

Now, I understand, the validation should be contained in commands: UpdateState would check if the entity current state allows transition to desired one, and would produce appropriate event StatusUpdated which would be persisted into the event store.

Question is, what should I do when replaying it back? Should I just update the status, or should I perform same validation (so that if status transition requirements change it won't be possible to load some previously updated entities unless we add some additional logic), to ensure we won't end up with entities that do not satisfy our current logic?

PS. I think I've got problems grasping it because in my understanding events are essentialy just about 'announcing' something that happened already (and the sender state is already modified) so that interesting parties can react accordingly. And in case of events loading/replaying, you need to alter said state instead of actually 'announce' anything...

Foi útil?

Solução

You do not need to perform any validation when replaying the event stream.

Commands model things that will be done in the future: You ask the system do to something for you. It's up to the system to decide whether to do it or not, e.g. based on business rules and validation.

Events in contrast model things that have already happened. As in the reality, you can not change the past.

So, this means, when an event gets persisted, it was in consequence of a command which was taken as valid at the point in time when it was processed. Replaying an event stream simply means to have a look at what happened in the past, and you can not change this.

Hence, you do not need to run any validation again.

Moreover, this means that if one day your business logic changes, all the things (business accidents!) that happened in the past still have happened, so they must not change. Hence you are not allowed to use any validation logic, as it may be another one today than when it was when you stored the events.

And again: You can not (and should not) change the past :-)

Example

Supposed you have a way of validating credit card numbers. A customer comes to your shop, pays, you consider his / her card as valid given your current set of rules, and everything is fine.

Then, one day the credit card institute changes the way credit card numbers are calculated, and hence you have another validation algorithm.

When you now play back your past events, the payment had happened, with or without the new validation rules - and you can not change the fact that it had happened! If you wanted to you had to create a new transaction to send money back to the customer. Again, this would result in a new event, not in a changed one from the past.

So, to cut a long story short: Don't validate events against anything. They are valid by definition, as they had happened before.

Outras dicas

Any event stream that's been written to the event store should be valid to be played back without introducing any logic in the event handlers. If you needed to change your transitioning process, you'd need to look at doing some sort of conversion, along the lines of this example.

Regarding your last point. Event sourcing is a technique for persisting and restoring the state of an entity using a historical record of ordered events. It just so happens that when you're saving the entity, you can also publish these events for any interested parties to consume.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top