Skip to content

Latest commit

 

History

History
77 lines (63 loc) · 3.36 KB

README.md

File metadata and controls

77 lines (63 loc) · 3.36 KB

Eventsourcing CQRS example in GO

Example event sourcing and CQRS implementation in golang

Project is a re-implementation of [https://github.com/pinballjs/event-sourcing-cqrs] in GO. Initial inspiration originates from Chris Richardson's presentation

How to run

git clone https://github.com/botchniaque/eventsourcing-cqrs-go.git
cd eventsourcing-cqrs-go/
export GOPATH=`pwd`
go get -t -v example eventsourcing
go build example
./example

to run tests

go test -v eventsourcing

Design

Example implements 2 aggregates - Account and Money Transfer

implementation includes number of components:

  • Event Store - persists events, and allows searching by aggregate ID.
  • Event Handler - gets notified about persisted events, and produces commands as a result of some events (eg. DebitAccountCommandBecauseOfMoneyTransfer when receives MoneyTransferCreatedEvent)
  • Command Handler - each aggregate has own handler, which produce state changing events, which then are persisted in the Event Store
  • Customer facing Services - expose usable functions to clients and produce commands as a product of interaction

Sketched diagram:

 +---------------+                        +--------------+
 | Event Handler |                        |  Event Store |
 |               |                        |   * Update   |
 |               +<---Persisted Events----+   * Find     |
 |               |        Channel         |              |
 +-------+-------+                        +------+-------+
         |                                       ^
      commands                                  events
         |                                       |
         |                             +---------+---------+
         +--------->                   | Command Handler   |
                    \                  |  - Account        |
                     +-----Command---> |  - Money Transfer |
                    /      Channel(s)  |                   |
            +------>                   +-------------------+
            |
         comamnds
            |
 +----------+--------+
 | Service           |
 |  - Account        |
 |    * Open         |
 |    * Credit       |
 |    * Debit        +<---Customer requests---+
 |  - Money Transfer |
 |    * Create new   |
 |                   |
 +-------------------+

What's missing

Message bus

After persisting, Event Store should publish events to a proper Message Bus where components can subscribe to those events. In the example, for simplification, the Persisted Events Channel works as a single-subscriber Message Bus - since channels are first-class citizens in GO, this simplified a lot, but it's not enough for real-life implementations.

To implement a simple bus allowing multiple subscribes, a 'linked channel' idea could be implemented as described here

Event (de)serialization

Example uses simple map/slice implementation of Event store. For real-life implementations events would need to be serialized (probably to JSON) for persistence. For simplification that part was omitted.