Modeling

Aggregate

The very first step is to model our domain. In the following example customer is considered as our aggregate:

@Value
@Builder(toBuilder = true)
public class Customer {
  @AggregateId
  private String id;
  private String firstName;
  private String lastName;
  private String address;

  // Getters & setters are omitted
}

Each aggregate is required to have an aggregate identifier annotated with @AggregateId. As without it, EasySourcing will not know to which aggregate a given command is targeted.

Commands

The next step is to create some commands for our aggregate.

@TopicInfo("customer-commands")
public interface CustomerCommand {

  @Value
  @Builder
  class CreateCustomer implements CustomerCommand {
    @AggregateId
    private String customerId;
    private String firstName;
    private String lastName;
  }

  @Value
  @Builder
  class ChangeFirstName implements CustomerCommand {
    @AggregateId
    private String customerId;
    private String firstName;
  }
}

Events

Our domain events are as follows:

@TopicInfo("customer-events")
public interface CustomerEvent {

  @Value
  @Builder
  class CustomerCreated implements CustomerEvent {
    @AggregateId
    private String customerId;
    private String firstName;
    private String lastName;
  }

  @Value
  @Builder
  class FirstNameChanged implements CustomerEvent {
    @AggregateId
    private String customerId;
    private String firstName;
  }
}

In the code snippets above, we have created some commands and events for our aggregate. We annotate our target aggregate identifier with @AggregateId. We also annotate our commands and events with @TopicInfo and specifiy the destination topics.

Best practises for choosing topic names:

  • Choose different topic names for commands and events. .
  • Choose different topic names for each aggregate type, for example 'customer-events' and 'order-events'.
  • Avoid topic names based on things that change, for example team name, topic owner, service name, product name, and consumer name.
  • Avoid topic names based on information that would be stored in other places.