Adding Event Sourcing to the Monolith
Explore how to add event sourcing to a Golang monolith by refactoring events into richer types that include metadata and support serialization. Understand the use of domain-driven design principles, the updated Event interface, and methods to manage aggregate-originated events. Gain hands-on knowledge of applying Go 1.18 features like generics to maintain type safety while handling events, enabling more scalable and maintainable asynchronous communication in your application.
We'll cover the following...
We added a domain-driven design package for the monolith to use called ddd. We will need to make some updates to this package and add a new one for our event sourcing needs.
Beyond basic events
The event code we used before was just what we needed. The needs specified were to make them straightforward to instantiate, convenient to reference as dependencies, and finally, easy to work with in our handlers.
type EventHandler func(ctx context.Context, event Event) errortype Event interface {EventName() string}
This old Event interface required that the plain old Go structs (POGSs) that we are using implement the EventName() method to be seen by the application as an Event.
Refactoring toward richer events
We have the following new needs:
We need to know the details of which aggregate the event originates from.
Events need to be serialized and deserialized so they can be written and read back out of the database.
With these new needs in mind, we need to revisit the events code in the ddd package and make some updates. The new interface for our event is shown in the following figure:
Looking at the new Event interface, some thoughts should spring to ...