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.