What is an Aggregate

An Aggregate is a group (a cluster) of objects that work together and are treated as a unit, to provide a specific functionality. It is the main building block of a business model. If you need more information about Aggregates, you can find it in the “Big Blue Book” or on the web.

Typically, when you implement the CQRS pattern, the classes in the write model define your aggregates. Aggregates are recipients of commands and units of persistence. After an aggregate instance has processed a command and applied events produced, Spine saves the new Aggregate state to a storage.

How to Define an Aggregate

An Aggregate is defined as a Java class which encapsulates and manages its state which is defined as a protobuf message.
The main steps to define an Aggregate are:

  • Select a type for identifiers of the aggregates. If you decide to use a typed identifier (which is recommended), you need to define a protobuf message for the ID type.
  • Define an aggregate state structure as a protobuf message.
  • Generate Java code for the ID and state types.
  • Create a new Aggregate class derived from the Aggregate base class, passing the ID and state type parameters:
public class OrderAggregate extends Aggregate<OrderId, Order> {
    // code of the aggregate
}

Constructor

An Aggregate must have a public constructor initializing an Aggregate ID. It must be public as it serves as a public API for Spine (it is used by the Repository).

public OrderAggregate(OrderId id) {
    super(id);
}

Command Handlers

An Aggregate contains Command Handlers, which are methods annotated with @Assign and have a command message and a command context as parameters. An example of the Command Handler of the OrderAggregate:

@Assign
public List<Message> handle(RegisterToConference command, CommandContext context) {
        validateCommand(command);
        final ImmutableList.Builder<Message> result = ImmutableList.builder();
        final boolean isNew = getVersion() == 0;
        if (isNew) {
            final OrderPlaced placedEvent = createOrderPlacedEvent(command);
            result.add(placedEvent);
        } else {
            final OrderUpdated updatedEvent = creatOrderUpdatedEvent(command);
            result.add(updatedEvent);
        }
        final OrderTotalsCalculated totalsCalculated = createOrderTotalsCalculatedEvent(command);
        result.add(totalsCalculated);
        return result.build();
    }

Event Appliers

An Event Applier is a method that modifies a state of an Aggregate with the data from the passed event. Event Appliers are not supposed to be called from the outside of the declaring aggregate class. As such they are declared private by convention set in the Spine framework. They are annotated with @Apply.

@Apply
 private void on(MyEvent event) {
     MyState newState = getState().toBuilder()
       .setMyProperty(event.getProperty())
       .build();
     validate(newState);
     incrementState(newState);
 }

By default there must be an Event Applier for each event generated by this Aggregate’s command handlers.

results matching ""

    No results matching ""