React

Marks a method of an entity as one that may modify the state of the entity in response to some domain event.

A reacting method must be annotated @React.

Like other message-handling methods, event reactors are designed to be called by the framework only. Therefore, it is recommended to declare a them as package-private. It discourages a developer from calling these methods directly from anywhere.

Package-private access level still declares that an event reactor method is a part of the Bounded Context-level API. See the BoundedContext description on how the packages and Bounded Contexts relate.

Accepted Parameters

Each reacting method must accept an event message derived from EventMessage as the first parameter. Optionally, one may pass some additional parameters and put the incoming message into some perspective.

Here are the available sets of parameters:

  • single event message:
    @React
     EngineStopped on(CarStopped event) { ... }
    
  • an event message along with its context; the context brings some system properties related to event, such as the actor ID and the timestamp of the event emission:
    @React
     ProjectOwnerAssigned on(ProjectCreated event, EventContext context) { ... }
    
  • if an event is a rejection event, one may additionally specify the command message, which led to this event; this will act like a filter:
    
    // Only rejections of `CannotAllocateCargo` type caused by the rejected `DeliverOrder` command will be dispatched.
    @React
     OrderDeliveryFailed on(CannotAllocateCargo event, DeliverOrder command) { ... }
    

    It is also possible to add the context of the origin command to access even more properties:

    @React
     ProjectRenameFailed on(ProjectAlreadyCompleted event, RenameProject command, CommandContext ctx) { ... }
    

Returning Values

The essence of a reacting method is an emission of one or several events in a reaction to the dispatched event. The emitted events must derive from EventMessage in order to make the code less error-prone.

As long as an entity may have a complex logic of determining which event to emit in reaction, the React-marked methods allow a variety of options for the returning values.

A reacting method must return either

  • an event message:
    @React
     TaskReassigned on(UserDeactivated event) { ... }
    
  • an Optional event message:
    @React
    Optional<PersonAllowedToBuyAlcohol> on(PersonAgeChanged event) { ... }
    
  • one of particular events; it also allows to use a special Nothing event stating that the entity may choose not to react at all:
    @React
    EitherOf3<ProjectCompleted, ProjectEstimateUpdated, Nothing> on(TaskCompleted event) { ... }
    
  • an Iterable of event messages:
    @React
    Iterable<StoryMovedToBacklog> on(SprintCompleted event) { ... }
    
  • a tuple of event messages; being similar to Iterable, tuples allow to declare the exact types of returning values, including Optional values:
    @React
    Pair<ProjectOwnerAssigned, ProjectDueDateChanged> on(ProjectCreated event) { ... }
    
    @React
    Pair<TaskAssigned, Optional<TaskStarted>> on(TaskAdded event) { ... }
    

If the annotation is applied to a method which does not satisfy either of these requirements, this method will not be registering for receiving events.

Functions

Link copied to clipboard
public abstract boolean external()
When true, the annotated method of the entity reacts on the event generated from outside of the Bounded Context to which this entity belongs.

Inherited functions

Link copied to clipboard
public abstract Class<? extends Annotation> annotationType()
Link copied to clipboard
public abstract boolean equals(Object p)
Link copied to clipboard
public abstract int hashCode()
Link copied to clipboard
public abstract String toString()