Assign
Marks a method as command handler.
A command handler method must:
- be annotated with @Assign;
- return an event message derived from EventMessage if there is only one event generated; or an
Iterable
of event messages for two or more events; - accept a command message derived from CommandMessage as the first parameter.
Like other message-handling methods, command handlers are designed to be called by the framework only. Therefore, it is recommended to declare them as package-private. It discourages a developer from calling these methods directly from anywhere.
Package-private access level still declares that a command handler method is a part of the Bounded Context-level API. See the BoundedContext description on how the packages and Bounded Contexts relate.
Accepted Parameters
The first parameter of the command handler always declares a type of the handled command.
A command handler method may accept a CommandContext as the second parameter, if handling of the command requires its context.
@Assign
TaskCreated handler(CreateTask command) { ... }
@Assign
TaskCompleted handler(CompleteTask command, CommandContext context) { ... }
In case a command may be rejected, a corresponding Throwable
should be declared:
@Assign
TaskStarted handler(StartTask command) throws TaskAlreadyInProgress { ... }
If the annotation is applied to a method which doesn't satisfy any of these requirements, this method is not considered a command handler and is not registered for command dispatching.
Returning Values
As a command is an imperative, it must lead to some outcome. Typically, a command results in an emission of one or more events. Each of them must derive from EventMessage in order to make the code less error-prone.
A command handler method must return either
- an event message:
@Assign TaskReassigned on(ReassignTask command) { ... }
Content copied to clipboard - an
Iterable
of event messages:@Assign Iterable<TaskCompleted> handler(CompleteProject event) { ... }
Content copied to clipboard - a tuple of event messages; being similar to
Iterable
, tuples allow to declare the exact types of returning values, includingOptional
values:@Assign Pair<ProjectCreated, ProjectAssigned> handlerCreateProject event) { ... } @Assign Pair<TaskCreated, Optional<TaskAssigned>> handler(CreateTask event) { ... }
Content copied to clipboard - one of particular events:
@Assign EitherOf2<TaskRemovedFromProject, TaskDeleted> handler(RemoveTask command) { ... }
Content copied to clipboard
One Handler per Command
An application must have one and only one handler per command message class. This includes the case of transforming an incoming command into one or more commands that will to be handled instead of the received one.
Declaring two methods that handle the same command class will result in run-time error.