Event Store
Events
An event is something that has occurred in the past, often with associated information.
An event stream is a uniquely-identified, ordered sequence of events.
Estoria represents an event as:
type Event struct {
ID typeid.ID
StreamID typeid.ID
StreamVersion int64
Timestamp time.Time
Data []byte
}
Event Stores
An event store reads events from and appends events to event streams.
Reading Streams
The ReadStream
method reads events from an event stream, returning a StreamIterator
that can be used to iterate over the events in the stream.
iter, _ := eventStore.ReadStream(ctx, streamID, eventstore.ReadStreamOptions{}) (StreamIterator, error)
for {
event, err := iter.Next(ctx)
if errors.Is(err, eventstore.ErrEndOfEventStream) {
break
}
// process event
}
Appending to Streams
The AppendStream
method appends one or more events to an event stream.
_ = eventStore.AppendStream(ctx, streamID, events []*eventstore.WritableEvent{
{Type: "balancechanged", Data: []byte(`{"amount": 100}`)},
}, eventstore.AppendStreamOptions{}) error
Event Store Implementations
For production applications, Estoria provides a number of vendor-specific event store implementations via the Component Library.
The core library also includes a simple in-memory event store for testing and prototyping.
Alternatively, you can implement your own event store. Anything implementing ReadStream
and AppendStream
can be used as an event store with Estoria:
import (
"github.com/go-estoria/estoria/eventstore"
"github.com/go-estoria/estoria/typeid"
)
interface {
AppendStream(context.Context, typeid.ID, []*eventstore.WritableEvent, eventstore.AppendStreamOptions) error
ReadStream(context.Context, typeid.ID, eventstore.ReadStreamOptions) (eventstore.StreamIterator, error)
}
Reading and writing event streams are low-level operations in Estoria. Next, we’ll see how to create an Aggregate Store that uses an event store to persist aggregates.