ThreeDotsLabs / watermill

Building event-driven applications the easy way in Go.
https://watermill.io
MIT License
6.8k stars 355 forks source link

Event sourcing support #8

Open roblaszczak opened 5 years ago

olpie101 commented 5 years ago

Hello,

I am keen on contributing. I am wondering if there are any design ideas for this component, that could form the basis of an initial discussion and/or implementation.

roblaszczak commented 5 years ago

Hello @olpie101. For this moment there aren't any written concept yet. If you have some ideas or sources feel free to post it here :)

roblaszczak commented 4 years ago

In progress! :) I will publish some proof of concepts soon.

blaggacao commented 3 years ago

Eventstore: https://dgraph.io/badger

See implementation for event sourcing: https://github.com/mishudark/eventhus/blob/master/eventstore/badger/badger.go

https://github.com/timshannon/badgerhold (for convenient read models)

Plus Polling-Publisher Message Relay https://microservices.io/patterns/data/polling-publisher.html

It also seems this might be a bit tricky with the current CQRS implementation:


Since one command may result in several events, it is also important never to persist only some events that result from executing a command. And so events must be appended to the event store in a single atomic transaction, so that if some of the events resulting from executing a command cannot be stored then none of them will be stored.

Source: https://eventsourcing.readthedocs.io/en/v3.0.0/topics/user_guide/aggregates_in_ddd.html


It seems this is the most compatible pattern I have found so far with watermill's cqrs implementation:

https://github.com/andrewwebber/cqrs

Specifically, since their implementation does not require handler in the form of aggregate methods, but uses plain old handler functions:

func(command cqrs.Command) error {
  changePasswordCommand := command.Body.(ChangePasswordCommand)
  // Load account from storage
  account, err := NewAccountFromHistory(changePasswordCommand.AccountID, repository)
  if err != nil {
    return err
  }

  account.ChangePassword(changePasswordCommand.NewPassword)

  // Persist new events
  repository.Save(account)  
  return nil
}
dronezzzko commented 1 year ago

@roblaszczak any updates on this?