Skip to content
Giau Tran Minh edited this page Dec 12, 2018 · 3 revisions

Define The Aggregate

Aggregate name

Every aggregate requires an AggregateType which is basically the aggregate name

const InvitationAggregateType eh.AggregateType = "Invitation"

Aggregate State

Define the state for the aggregate which will be used to validate commands against business logic. The only required field is the *events.AggregateBase, which is explained in the next section.

type InvitationAggregate struct {
	// AggregateBase implements most of the eventhorizon.Aggregate interface.
	*events.AggregateBase

	name string
	age  int

	// TODO: Replace with FSM.
	accepted  bool
	declined  bool
	confirmed bool
	denied    bool
}

Aggregate Base

The aggregate base stores:

  • The aggregate ID (a globally unique identifier)
  • The aggregate type
  • The aggregate version (tracks the number of events committed to each instance of the aggregate)
  • The events that have been applied to the aggregate

Command Handler

The following function needs to be implemented to handle every command on the aggregate

func (a *InvitationAggregate) HandleCommand(ctx context.Context, cmd eh.Command) error {
    switch cmd.(type) {
    ...
    }
}

Every command for this aggregate should be handled within this function. This is where your business rules will be implemented.

Access the latest Aggregate State using the a parameter. Use the state stored in the a Aggregate to validate business logic for each command before storing an event.

If the business logic succeeds and you wish to append an event (such as InviteAcceptedEvent) to the aggregate then call:

a.StoreEvent(InviteAcceptedEvent, nil, time.Now())

or if the event has data associated with it that was given through the command

a.StoreEvent(InviteCreatedEvent,
	&InviteCreatedData{
		cmd.Name,
		cmd.Age,
	},
	time.Now(),
)

If there is a violation of business rules then return an error, otherwise return nil

Event Applier

To update the aggregate state, the event needs to be handled in the ApplyEvent method:

func (a *InvitationAggregate) ApplyEvent(ctx context.Context, event eh.Event) error {
	switch event.EventType() {
	}
}

Taken from the example

Clone this wiki locally