Services are responsible for mapping each external request to a command object and sending it to a new or existing aggregate. A service is often invoked by a Micronaut or Spring MVC Controller, but can also be invoked by an integration framework such as Spring Integration in response to a message.
The Eventuate client framework for Java supports several different ways to implement services.
The simplest approach is to use an AggregateRepository
.
AggregateRepository
classAggregateRepository
is a generic class that has two type parameters: the aggregate class and the command class.
It encapsulates the boilerplate logic you will use to access the Event Store, in lieu of writing logic from scratch each time.
AggregateRepository
defines the following methods:
Both methods are asynchronous and return a CompletableFuture
containing the updated aggregate.
Here is an example AccountService that uses an AggregateRepository
:
public class AccountService {
private final AggregateRepository<Account, JavaAccountCommand> accountRepository;
public AccountService(AggregateRepository<Account, JavaAccountCommand>
accountRepository) {
this.accountRepository = accountRepository;
}
public CompletableFuture<EntityWithIdAndVersion<Account>>
openAccount(BigDecimal initialBalance) {
return accountRepository.save(new JavaOpenAccountCommand(initialBalance));
}
}
Instead of using an AggregateRepository
you can write services that use the Event Store API directly.
The low-level API is much more flexible but requires you to write much more code.
It consists of an EventuateAggregateStore
interface, which you can inject into your event handling code.
It defines various methods for creating, updating and retrieving aggregates.