Aggregate Root - Logical Model

The logical model of the Aggregate Root is purely behavioral. The Aggregate Root exposes a set of business operations (commands) related to a business entity/case. When a command is received, it is validated against the current state of the AR and either it is accepted or rejected. If a command is accepted, an event (or a sequence of events) is stored in the AR journal and the state of the AR is updated. The state of the AR is its internal property, that can never be accessed directly from the outside of the AR. Thus, the structure of the AR (the structure of the AR state) is not a property of the AR logical model.

The logical model of the AR can only be defined as a set of behavior scenarios / specifications, each expressed in the following form:

Aggregate Root - Behavior Specification

Given

        a sequence of commands CG-1...CG-n accepted

When

        a command CR received

Then

        an event E (or a sequence of events E-1...E-n) stored in the AR journal
        or
        the command CR rejected due to a reason R
 

Not surprisingly, the AR logical model defined as a set of AR behavior specifications is a perfectly valid, complete specification of the unit test that the AR implementation should be accompanied by.

Following, is a single behavior specification for the Reservation AR, implemented as a unit test using Given-When-Then test fixture provided by the Akka-DDD:

"Reservation office" should {
    "confirm reservation" in {
      given(
        CreateReservation(reservationId, "client1"),
        ReserveProduct(reservationId, product, quantity = 1)
      )
      .when(
        ConfirmReservation(reservationId)
      )
      .expectEvent {
        ReservationConfirmed(reservationId, "client1", product.price)
      }
    }
}

See: Testing Aggregate Root

Aggregate Root ID

Aggregate Root ID is the identifier of the associated business entity/case. All commands are expected to inherit from the Command trait to be able to expose the Aggregate Root ID (by implementing the [aggregateId() method).