Documentation
¶
Overview ¶
Package aggregate provides a base implementation for event sourced aggregates.
To create an event sourced aggregate, a user must define their own domain aggregate that implements the cqrs.Aggregate interface. The user's domain aggregate should define its own identifier type and event type.
Additionally, command handlers and event appliers should be defined within the user's domain aggregate. The command handlers handle commands and produce events, while the event appliers apply events to update the aggregate's state.
Once the user's domain aggregate is defined, it can be transformed into a cqrs.ESAggregate using the aggregate.FromAggregate function. This function automatically registers the command handlers and event appliers defined in the user's domain aggregate.
For a detailed example of how to use the aggregate package, please refer to the Example function in the example_test.go file.
More examples can be found in the examples directory.
Example ¶
Example demonstrates the use of the aggregate package to handle a command and produce events.
package main import ( "fmt" "github.com/screwyprof/cqrs" "github.com/screwyprof/cqrs/aggregate" ) const AggregateType = "MyAggregate" // Identifier is a user-defined type that implements the fmt.Stringer interface. type Identifier = fmt.Stringer // Event is a user-defined interface that represents events in the domain. type Event interface { EventType() string } // MyIdentifier is a user-defined identifier that implements the Identifier interface. type MyIdentifier string func (id MyIdentifier) String() string { return string(id) } // SomethingHappened is a user-defined event that implements the Event interface. type SomethingHappened struct { ID MyIdentifier Changed bool } func (e SomethingHappened) EventType() string { return "SomethingHappened" } // MyAggregate is a user-defined aggregate that will handle commands and apply events. type MyAggregate struct { id MyIdentifier isModified bool } func (a *MyAggregate) AggregateID() Identifier { return a.id } func (a *MyAggregate) AggregateType() string { return AggregateType } // DoSomething is an example of a command. type DoSomething struct { ID MyIdentifier } func (c DoSomething) AggregateID() cqrs.Identifier { return c.ID } func (c DoSomething) AggregateType() string { return AggregateType } func (c DoSomething) CommandType() string { return "DoSomething" } // DoSomething is a command handler method for the MyAggregate. func (a *MyAggregate) DoSomething(c DoSomething) ([]Event, error) { e := SomethingHappened{ ID: c.ID, Changed: true, } return []Event{e}, nil } // OnSomethingHappened is an event applier method for the MyAggregate. func (a *MyAggregate) OnSomethingHappened(e SomethingHappened) { a.isModified = e.Changed } // Example demonstrates the use of the aggregate package to handle a command and produce events. func main() { id := MyIdentifier("123") agg := &MyAggregate{id: id} esAgg := aggregate.FromAggregate(agg) events, err := esAgg.Handle(DoSomething{ID: id}) if err != nil { fmt.Printf("an error occurred: %v\n", err) return } fmt.Printf("Produced events: %v\n", events) }
Output: Produced events: [{123 true}]
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrCommandHandlerNotFound is returned when a command handler is not found. ErrCommandHandlerNotFound = errors.New("command handler not found") // ErrEventApplierNotFound is returned when an event applier is not found. ErrEventApplierNotFound = errors.New("event applier not found") // ErrAggregateNotRegistered is returned when an aggregate is not registered in the factory. ErrAggregateNotRegistered = errors.New("aggregate is not registered") )
Functions ¶
This section is empty.
Types ¶
type CommandHandler ¶ added in v0.5.0
type CommandHandler struct {
// contains filtered or unexported fields
}
CommandHandler registers and handles commands.
func NewCommandHandler ¶ added in v0.5.0
func NewCommandHandler() *CommandHandler
NewCommandHandler creates a new instance of CommandHandler.
func (*CommandHandler) Handle ¶ added in v0.5.0
func (h *CommandHandler) Handle(c cqrs.Command) ([]cqrs.DomainEvent, error)
Handle implements cqrs.CommandHandler interface.
func (*CommandHandler) RegisterHandler ¶ added in v0.5.0
func (h *CommandHandler) RegisterHandler(method string, handler cqrs.CommandHandlerFunc)
RegisterHandler registers a command handler for the given method.
func (*CommandHandler) RegisterHandlers ¶ added in v0.5.0
func (h *CommandHandler) RegisterHandlers(aggregate cqrs.Aggregate)
RegisterHandlers registers all the command handlers found in the aggregate.
type EventApplier ¶ added in v0.5.0
type EventApplier struct {
// contains filtered or unexported fields
}
EventApplier applies events for the registered appliers.
func NewEventApplier ¶ added in v0.5.0
func NewEventApplier() *EventApplier
NewEventApplier creates a new instance of EventApplier.
func (*EventApplier) Apply ¶ added in v0.5.0
func (a *EventApplier) Apply(events ...cqrs.DomainEvent) error
Apply implements cqrs.EventApplier interface.
func (*EventApplier) RegisterApplier ¶ added in v0.5.0
func (a *EventApplier) RegisterApplier(method string, applier cqrs.EventApplierFunc)
RegisterApplier registers an event applier for the given method.
func (*EventApplier) RegisterAppliers ¶ added in v0.5.0
func (a *EventApplier) RegisterAppliers(aggregate cqrs.Aggregate)
RegisterAppliers registers all the event appliers found in the aggregate.
type EventSourced ¶ added in v0.6.0
EventSourced is an aggregate that implements CQRS and Event Sourcing.
It composes cqrs.Aggregate, cqrs.CommandHandler, and cqrs.EventApplier interfaces.
func FromAggregate ¶ added in v0.6.0
func FromAggregate(agg cqrs.Aggregate) *EventSourced
FromAggregate takes a cqrs.Aggregate and returns a cqrs.ESAggregate.
It automatically registers all the command handlers and event appliers found in the aggregate.
func New ¶ added in v0.6.0
func New(aggregate cqrs.Aggregate, commandHandler cqrs.CommandHandler, eventApplier cqrs.EventApplier) *EventSourced
New creates a new instance of EventSourced.
It requires a basic cqrs.Aggregate, a cqrs.CommandHandler, and a cqrs.EventApplier as parameters. It returns a pointer to an EventSourced instance.
func (*EventSourced) Apply ¶ added in v0.6.0
func (b *EventSourced) Apply(e ...cqrs.DomainEvent) error
Apply applies the given domain events to the aggregate.
It applies the events and updates the aggregate version. It implements the cqrs.EventApplier interface.
func (*EventSourced) Handle ¶ added in v0.6.0
func (b *EventSourced) Handle(c cqrs.Command) ([]cqrs.DomainEvent, error)
Handle processes the given command and produces relevant domain events.
It handles this given command and applies the produced events.
It implements the cqrs.CommandHandler interface.
func (*EventSourced) Version ¶ added in v0.6.0
func (b *EventSourced) Version() int
Version returns the current version of the aggregate.
It implements the cqrs.Versionable interface.
type Factory ¶ added in v0.5.0
type Factory struct {
// contains filtered or unexported fields
}
Factory is responsible for creating aggregates by their type. It maintains a registry of factory functions for different aggregate types.
func NewFactory ¶ added in v0.5.0
func NewFactory() *Factory
NewFactory creates a new instance of Factory and initializes its internal factory registry. It returns a pointer to the created Factory instance.
func (*Factory) CreateAggregate ¶ added in v0.5.0
func (f *Factory) CreateAggregate(aggregateType string, id cqrs.Identifier) (cqrs.ESAggregate, error)
CreateAggregate creates an aggregate of a given type.
It uses the registered factory function to create an instance of the aggregate. It returns an error if the requested aggregate type is not registered in the factory.