@Retention(value=RUNTIME)
@Target(value=METHOD)
public @interface Assign
A command handler method must:
@Assign
;
EventMessage
if there is only one event generated;
or an Iterable
of event messages for two or
more events;
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 a 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.
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.
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
@Assign TaskReassigned on(ReassignTask command) { ... }
Iterable
of event messages:
@Assign Iterable<TaskCompleted> handler(CompleteProject event) { ... }
tuple
of event messages; being similar
to Iterable
, tuples allow to declare the exact types of returning values, including
Optional
values:
@Assign Pair<ProjectCreated, ProjectAssigned> handlerCreateProject event) { ... } @Assign Pair<TaskCreated, Optional<TaskAssigned>> handler(CreateTask event) { ... }
@Assign EitherOf2<TaskRemovedFromProject, TaskDeleted> handler(RemoveTask 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.