Command

Command is a request for changes in the domain. Unlike an event, it is not a statement of fact as it might be rejected, throw an exception or produce no events or produce events that the requestor might have not anticipated.

Defining a command is pretty straightforward, through subclassing StandardCommand<State, Result>:

@Value
@EqualsAndHashCode(callSuper = false)
@Accessors(fluent = true)
public class RegisterRestaurant extends StandardCommand<RestaurantRegistered, Restaurant> {

    private String name;
    private Address address;
    private OpeningHours openDuring;

Because of Lombok's @Value annotation, this class has an autogenerated constructor with the above fields included.

The first type parameter signifies the type of the state passed between events() and result().

The last type parameter signifies an result type that can be returned once the command is successfully executed, by overriding the result() method:

@Override public Restaurant result(RestaurantRegistered restaurantRegistered, Repository repository) {
    return Restaurant.lookup(repository, restaurantRegistered.uuid()).get();
}

A more important part of any command is being able to generate events. This is done by overriding the events() method that returns a stream of events with an associated state:

@Override public EventStream<RestaurantRegistered> events() throws Exception {
    RestaurantRegistered restaurantRegistered = new RestaurantRegistered();
    NameChanged nameChanged = new NameChanged(restaurantRegistered.uuid(), name);
    AddressChanged addressChanged = new AddressChanged(restaurantRegistered.uuid(), address);
    Stream<WorkingHoursChanged> workingHoursChangedStream =
            Arrays.asList(DayOfWeek.values()).stream()
                  .map(dayOfWeek -> new WorkingHoursChanged(restaurantRegistered.uuid(),
                                                            dayOfWeek, Collections.singletonList(openDuring)));
    return EventStream.ofWithState(restaurantRegistered,
                                   Stream.concat(
                                     Stream.of(restaurantRegistered, nameChanged, addressChanged),
                                     workingHoursChangedStream
                                   ));
}

results matching ""

    No results matching ""