Documentation ¶
Index ¶
- Constants
- func ApplyHistory[Events ~[]event.Of[any]](a Aggregate, events Events) error
- func IsConsistencyError(err error) bool
- func Next[Data any](a Aggregate, name string, data Data, opts ...event.Option) event.Evt[Data]
- func NextEvent[D any](a Aggregate, name string, data D, opts ...event.Option) event.Evt[D]deprecated
- func NextVersion(a Aggregate) int
- func UncommittedVersion(a Aggregate) int
- func ValidateConsistency[Data any, Events ~[]event.Of[Data]](ref Ref, currentVersion int, events Events, opts ...ConsistencyOption) error
- type Aggregate
- type Base
- func (b *Base) Aggregate() (uuid.UUID, string, int)
- func (b *Base) AggregateChanges() []event.Event
- func (b *Base) AggregateID() uuid.UUID
- func (b *Base) AggregateName() string
- func (b *Base) AggregateVersion() int
- func (b *Base) ApplyEvent(evt event.Event)
- func (b *Base) Commit()
- func (b *Base) CurrentVersion() int
- func (b *Base) DiscardChanges()
- func (b *Base) ModelID() uuid.UUID
- func (b *Base) RecordChange(events ...event.Event)
- func (b *Base) Ref() Ref
- func (b *Base) SetVersion(v int)
- type Committer
- type ConsistencyError
- type ConsistencyKind
- type ConsistencyOption
- type History
- type Of
- type Option
- type Query
- type Ref
- type Repository
- type SoftDeleter
- type SoftRestorer
- type SortDirection
- type SortOptions
- type Sorting
- type TypedAggregate
- type TypedRepository
Constants ¶
const ( // InconsistentID is a ConsistencyKind indicating that an event has an // inconsistent AggregateID with the expected one. InconsistentID = ConsistencyKind(iota + 1) // InconsistentName is a ConsistencyKind representing an error caused by an // event having an invalid AggregateName that does not match the expected name // for the aggregate. InconsistentName // InconsistentVersion indicates an inconsistency in the version of an Event // within an Aggregate. This occurs when the version of an event is less than or // equal to the current version of the aggregate, or when the version of a new // event is less than or equal to the version of a previous event. InconsistentVersion // InconsistentTime indicates that an event has an invalid time, meaning it // occurred before its preceding event in the sequence of events being // validated. InconsistentTime )
const ( // SortName is a Sorting option that compares two Aggregates by their names in // ascending order. It is used in the Query interface for specifying the desired // sorting method when querying Aggregates. SortName = Sorting(iota) // SortID is a Sorting value used to sort Aggregates by their ID when comparing // them. SortID // SortVersion is a Sorting option that compares Aggregates based on their // version, ordering them by ascending or descending version numbers depending // on the SortDirection. SortVersion // SortAsc is a SortDirection that indicates sorting of aggregates in ascending // order based on the specified Sorting criteria. SortAsc = SortDirection(iota) // SortDesc is a [SortDirection] constant that specifies the descending order // for sorting Aggregates by their name, ID, or version. SortDesc )
Variables ¶
This section is empty.
Functions ¶
func ApplyHistory ¶
ApplyHistory applies a sequence of events to the given Aggregate, ensuring consistency before applying. If the Aggregate implements the Committer interface, changes are recorded and committed after applying the events. Returns an error if consistency validation fails.
func IsConsistencyError ¶ added in v0.1.2
IsConsistencyError checks if the given error is a ConsistencyError or an error implementing the IsConsistencyError method returning true.
func Next ¶ added in v0.1.2
Next creates a new event with the provided name and data, applies it to the given aggregate, and records the change if the aggregate implements the Committer interface. The event is assigned the next available version and a timestamp that is guaranteed to be at least 1 nanosecond after the previous event.
func NextVersion ¶
NextVersion returns the next version number for the given Aggregate, taking into account both its committed and uncommitted changes.
func UncommittedVersion ¶
UncommittedVersion returns the version of the given Aggregate after applying all uncommitted changes. It takes into account both the current version and any uncommitted events to calculate the resulting version.
func ValidateConsistency ¶
func ValidateConsistency[Data any, Events ~[]event.Of[Data]](ref Ref, currentVersion int, events Events, opts ...ConsistencyOption) error
ValidateConsistency checks the consistency of the provided events with the given aggregate reference and current version. It returns a ConsistencyError if any inconsistency is found, such as mismatched IDs, names, versions, or event times. The consistency check can be configured with ConsistencyOption functions.
Types ¶
type Aggregate ¶
Aggregate represents an entity that encapsulates a collection of events and their resulting state. It provides methods to apply new events, access the current state, and retrieve the list of uncommitted changes. It can also be used in conjunction with Committer to record and commit changes. Additionally, Aggregate supports soft deletion and restoration through the SoftDeleter and SoftRestorer interfaces.
func Sort ¶
func Sort(as []Aggregate, s Sorting, dir SortDirection) []Aggregate
Sort sorts the given Aggregates ([]Aggregate) according to the specified Sorting and SortDirection. The sorted Aggregates are returned as a new slice without modifying the input slice.
func SortMulti ¶
func SortMulti(as []Aggregate, sorts ...SortOptions) []Aggregate
SortMulti sorts a slice of Aggregates by multiple SortOptions in the order they are provided. If two Aggregates have the same value for a SortOption, the next SortOption in the list is used to determine their order.
type Base ¶
type Base struct { ID uuid.UUID Name string Version int Changes []event.Event // contains filtered or unexported fields }
Base provides the core of an event-sourced aggregate. When embedded into an aggregate, the aggregate will implement these APIs:
- aggregate.Aggregate
- aggregate.Committer
- repository.ChangeDiscarder
- snapshot.Aggregate
func New ¶
New creates a new Base aggregate with the specified name and UUID, applying the provided options. The returned Base can be embedded into custom aggregates to provide core functionality for event-sourced aggregates.
func (*Base) Aggregate ¶
Aggregate returns the ID, name, and version of an event-sourced aggregate. It is used to retrieve information about the aggregate without accessing its fields directly.
func (*Base) AggregateChanges ¶
AggregateChanges returns the uncommitted changes (events) of the event-sourced aggregate. These are the events that have been recorded but not yet committed to the event store.
func (*Base) AggregateID ¶
AggregateID returns the UUID of the aggregate associated with the Base struct.
func (*Base) AggregateName ¶
AggregateName returns the name of the aggregate.
func (*Base) AggregateVersion ¶
AggregateVersion returns the current version of the aggregate. The version is incremented when events are committed to the aggregate.
func (*Base) ApplyEvent ¶
ApplyEvent applies the given event to the aggregate by calling the appropriate event handler registered for the event's name. The event must have been created with the aggregate's ID, name, and version.
func (*Base) Commit ¶
func (b *Base) Commit()
Commit updates the aggregate version to the version of its latest change and clears the changes. If there are no changes, nothing is done.
func (*Base) CurrentVersion ¶ added in v0.2.0
CurrentVersion returns the current version of the aggregate, which is the sum of its base version and the number of uncommitted changes.
func (*Base) DiscardChanges ¶ added in v0.1.2
func (b *Base) DiscardChanges()
DiscardChanges resets the list of recorded changes to an empty state, effectively discarding any uncommitted changes made to the aggregate.
func (*Base) ModelID ¶ added in v0.1.2
ModelID returns the UUID of the aggregate that the Base is embedded into.
func (*Base) RecordChange ¶ added in v0.1.2
RecordChange appends the provided events to the Changes slice of the Base aggregate.
func (*Base) Ref ¶ added in v0.2.0
Ref returns a Ref object containing the Name and ID of the aggregate.
func (*Base) SetVersion ¶
SetVersion manually sets the version of the aggregate.
SetVersion implements snapshot.Aggregate.
type Committer ¶
type Committer interface { // RecordChange records the given events and associates them with the aggregate // in the Committer. These events will be applied and persisted when Commit is // called. RecordChange(...event.Event) // Commit records the changes made to an aggregate by appending the recorded // events to the aggregate's event stream. Commit() }
Committer is an interface that handles recording and committing changes in the form of events to an aggregate. It provides methods for recording changes as a series of events and committing them to update the aggregate's state.
type ConsistencyError ¶
type ConsistencyError struct { Kind ConsistencyKind Aggregate Ref CurrentVersion int Events []event.Event EventIndex int }
ConsistencyError represents an error that occurs when the consistency of an aggregate's events is violated. It provides information about the kind of inconsistency, the aggregate reference, the current version of the aggregate, the list of events, and the index of the event causing the inconsistency.
func (*ConsistencyError) Error ¶
func (err *ConsistencyError) Error() string
Error returns a string representation of the ConsistencyError, describing the inconsistency found in the aggregate event. It includes details such as the event name, expected and actual values for AggregateID, AggregateName, AggregateVersion, or Time depending on the Kind of inconsistency.
func (*ConsistencyError) Event ¶
func (err *ConsistencyError) Event() event.Event
Event returns the event that caused the ConsistencyError at the EventIndex. If the EventIndex is out of bounds, it returns nil.
func (*ConsistencyError) IsConsistencyError ¶ added in v0.1.2
func (err *ConsistencyError) IsConsistencyError() bool
IsConsistencyError determines if the given error is a ConsistencyError or an error that implements the IsConsistencyError method. It returns true if either condition is met, otherwise false.
type ConsistencyKind ¶
type ConsistencyKind int
ConsistencyKind represents the kind of inconsistency found in an aggregate's events when validating their consistency. Possible kinds are InconsistentID, InconsistentName, InconsistentVersion, and InconsistentTime.
func (ConsistencyKind) String ¶
func (k ConsistencyKind) String() string
String returns a string representation of the ConsistencyKind value, such as "<InconsistentID>", "<InconsistentName>", "<InconsistentVersion>", or "<InconsistentTime>".
type ConsistencyOption ¶ added in v0.2.9
type ConsistencyOption func(*consistencyValidation)
ConsistencyOption is a functional option type used to configure consistency validation for event aggregates. It allows customizing the behavior of the ValidateConsistency function, such as ignoring time consistency checks.
func IgnoreTime ¶ added in v0.2.9
func IgnoreTime(ignore bool) ConsistencyOption
IgnoreTime returns a ConsistencyOption that configures whether time consistency checks should be ignored when validating aggregate event consistency. If set to true, the validation will not check if events are ordered by their time.
type History ¶
type History interface { // Aggregate returns the Ref of the aggregate to which this History belongs. It // also applies the history to the given Aggregate, ensuring that events are // applied in a consistent manner. Aggregate() Ref // Apply applies the history of events to the given Aggregate, ensuring // consistency and updating the Aggregate's state accordingly. If the Aggregate // implements the Committer interface, changes are recorded and committed. Apply(Aggregate) }
History represents an interface for managing the application and consistency of events on an Aggregate. It provides methods to reference the associated Aggregate and apply changes to it.
type Of ¶ added in v0.1.2
type Of[ID comparable] interface { // Aggregate returns the ID, name, and version of an [Of] aggregate. It also // provides methods for obtaining the aggregate's changes as a slice of // [event.Event] and applying an event to the aggregate. Aggregate() (ID, string, int) // AggregateChanges returns a slice of all uncommitted events that have been // recorded for the aggregate. AggregateChanges() []event.Event // ApplyEvent applies the given event.Event to the aggregate, updating its state // according to the event data. ApplyEvent(event.Event) }
Of is an interface that represents an event-sourced aggregate with a comparable ID. It provides methods to access the aggregate's ID, name, version, and uncommitted changes, as well as to apply an event to the aggregate. Implementations of this interface can be used alongside other types such as Committer, SoftDeleter, and SoftRestorer to facilitate event sourcing and soft deletion/restoration of aggregates.
type Option ¶
type Option func(*Base)
Option is a function that configures a Base aggregate. It is used as an argument in the New function to customize the created aggregate.
type Query ¶
type Query interface { // Names returns a slice of aggregate names to be included in the query. Names() []string // IDs returns a slice of UUIDs that the Query is constrained to. IDs() []uuid.UUID // Versions returns the version constraints for a Query, which are used to // filter the queried Aggregates based on their version. Versions() version.Constraints // Sortings returns a slice of SortOptions that represent the sorting options // applied to a Query. The sorting options dictate the order in which Aggregates // are returned when executing the Query. Sortings() []SortOptions }
Query represents a set of criteria for filtering and sorting Aggregates in a Repository. It defines which Aggregates should be included based on their names, IDs, and versions, as well as the order in which they should be sorted.
type Ref ¶
type Ref = event.AggregateRef
Ref is a reference to a specific aggregate, identified by its name and id.
type Repository ¶
type Repository interface { // Save persists the given Aggregate to the Repository. Returns an error if the // operation fails. Save(ctx context.Context, a Aggregate) error // Fetch retrieves the latest state of the specified Aggregate from the // Repository and updates its state. It returns an error if the Aggregate cannot // be fetched. Fetch(ctx context.Context, a Aggregate) error // FetchVersion retrieves the specified version of an Aggregate from the // Repository and updates the provided Aggregate with the fetched data. It // returns an error if the version cannot be fetched or if the provided // Aggregate is not compatible with the fetched data. FetchVersion(ctx context.Context, a Aggregate, v int) error // Query executes a query on the Repository and returns channels for receiving // aggregate histories and errors. It takes a context and a Query as arguments. Query(ctx context.Context, q Query) (<-chan History, <-chan error, error) // Use applies the provided function fn to the given Aggregate a inside a // Repository, ensuring proper synchronization and error handling in the given // context. The function returns an error if any occurs during the execution of // fn or while interacting with the Repository. Use(ctx context.Context, a Aggregate, fn func() error) error // Delete removes the specified Aggregate from the Repository. It returns an // error if the deletion fails. Delete(ctx context.Context, a Aggregate) error }
Repository is an interface for persisting, fetching, querying, and deleting Aggregates. It provides methods for saving and fetching specific versions of an Aggregate, as well as querying multiple Aggregates based on a Query specification.
type SoftDeleter ¶ added in v0.1.2
type SoftDeleter interface{ SoftDelete() bool }
SoftDeleter is an API that can be implemented by event data to soft-delete an aggregate. Soft-deleted aggregates are excluded from query results of the aggregate repository. When trying to fetch a soft-deleted aggregate from a repository, a repository.ErrDeleted error is returned. Soft-deleted aggregates can be restored by SoftRestorer events.
To soft-delete an aggregate, an event with event data that implements SoftDeleter must be inserted into the aggregate's event stream. The SoftDelete() method of the event data must return true if the aggregate should be soft-deleted.
type DeletedData struct {} func (DeletedData) SoftDelete() bool { return true } type Foo struct { *aggregate.Base } func (f *Foo) Delete() { aggregate.Next(f, "foo.deleted", DeletedData{}) }
type SoftRestorer ¶ added in v0.1.2
type SoftRestorer interface{ SoftRestore() bool }
SoftRestorer is an API that can be implemented by event data to restore a soft-deleted aggregate.
To restore a soft-deleted aggregate, an event with event data that implements SoftRestorer must be inserted into the aggregate's event stream. The SoftDelete() method of the event data must return true if the aggregate should be restored.
type RestoredData struct {} func (RestoredData) SoftRestore() bool { return true } type Foo struct { *aggregate.Base } func (f *Foo) Delete() { aggregate.Next(f, "foo.restored", RestoredData{}) }
type SortDirection ¶
type SortDirection int
SortDirection is an enumeration representing the direction of sorting (ascending or descending) when comparing Aggregates in a Query. It is used alongside Sorting to define the sorting criteria for querying Aggregates from a Repository.
func (SortDirection) Bool ¶
func (dir SortDirection) Bool(b bool) bool
Bool returns true if the SortDirection is SortAsc and the given boolean is true, or if the SortDirection is SortDesc and the given boolean is false. Otherwise, it returns false.
type SortOptions ¶
type SortOptions struct { Sort Sorting Dir SortDirection }
SortOptions is a struct that defines the sorting configuration for a query by specifying the sort field (Sorting) and sort direction (SortDirection). It is used in Query to determine the order of returned Aggregates.
type Sorting ¶
type Sorting int
Sorting is a type that represents the sorting criteria for Aggregates in a Query. It provides methods to compare Aggregates based on their name, ID, or version. Use the constants SortName, SortID, and SortVersion to specify the desired sorting criteria.
type TypedAggregate ¶ added in v0.1.2
TypedAggregate is an interface that composes the model.Model[uuid.UUID] and Aggregate interfaces, providing functionality for creating, fetching, and manipulating Aggregates with UUIDs as their identifier.
type TypedRepository ¶ added in v0.1.2
type TypedRepository[A TypedAggregate] interface { model.Repository[A, uuid.UUID] // FetchVersion retrieves an Aggregate with the specified UUID and version from // the TypedRepository. It returns the fetched Aggregate and an error if any // occurs during the fetch operation. FetchVersion(ctx context.Context, id uuid.UUID, version int) (A, error) // Query returns a channel of [TypedAggregate]s that match the specified query, // a channel for errors during the query execution, and an error if the query // can't be started. The returned channels must be fully consumed to avoid // goroutine leaks. Query(ctx context.Context, q Query) (<-chan A, <-chan error, error) }
TypedRepository is a specialized Repository for managing TypedAggregate instances, providing additional methods for fetching specific versions of an aggregate and querying with type safety. It extends the functionality of model.Repository, allowing for more fine-grained control over aggregate persistence and retrieval.