aggregate

package
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 3, 2023 License: MIT Imports: 5 Imported by: 0

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

View Source
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

type EventSourced struct {
	cqrs.Aggregate
	// contains filtered or unexported fields
}

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.

func (*Factory) RegisterAggregate added in v0.5.0

func (f *Factory) RegisterAggregate(aggregateType string, factory cqrs.FactoryFn)

RegisterAggregate registers an aggregate factory method.

The factory function is used to create aggregates of a specific type.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL