@Retention(value=RUNTIME)
@Target(value=METHOD)
@AcceptsExternal
public @interface Command
A commanding method must:
@Command
;
Like other message-handling methods, commanding methods 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.
Commanding methods may be used to transform an incoming command with one or more commands. In this case the first method parameter must extend CommandMessage. The returning values must derive from the CommandMessage as well.
If a commanding method accepts a command type which is also handled by the application by another method, a run-time error will occur. This also means that an application cannot have two command-handling methods that accept the same command type.
There are several combinations of accepted parameters for a command-transforming method. The set of available parameters include
@Command ArchiveTask on(DeleteTask command) { ... }
@Command MoveTaskToDone on(CompleteTask command, CommandContext context) { ... }
A command-transforming method always returns an outcome. Depending on the design intention, a type of an outcome may vary.
The command-transforming method must return either
@Command AssignTask on(StartTask command) { ... }
@Command EitherOf2<StopTask, PauseTask> on(RemoveTaskFromProject command) { ... }
Iterable
of command messages:
@Command Iterable<PauseTask> on(PauseProject command) { ... }
tuple
of several command messages; being similar
to Iterable
, tuples allow to declare the exact types of returning values, including
Optional
values:
@Command Pair<AssignTask, Optional<StartTask>> on(AddTaskToProject command) { ... }
As a command-handling method, a command-transforming method may reject an incoming command.
In this case, it should declare a generated class derived from
ThrowableMessage
in throws
clause:
@Command AssignProject on(CreateProject command) throws CannotCreateProject { ... }
Throwing other types of Throwable
s is not allowed in
the command-transforming methods.
A commanding method may serve to emit commands in response to an incoming event. In this case
its first parameter must be a message of either EventMessage
or RejectionMessage
type.
Command-reaction method must accept either
@Command ScheduleDelivery on(OrderPaid command) { ... }
@Command NotifyCustomer on(DeliveryScheduled event, EventContext context) { ... }
@Command CreateProject on(Rejections.CannotCreateProject rejection) { // Change the parameters and try again. }
@Command ReassignTask on(Rejections.CannotStartTask rejection, CommandContext) { ... }
It is possible to receive external Events and Rejections. For that, mark the message parameter
with the @External
annotation. External Commands do not travel
this way.
A command-reacting method may emit one more more messages deriving from
CommandMessage
. The possibilities for the return values
are flexible. They serve to describe the returning values as sharp as possible and thus
reduce the probability of a human mistake.
A command-reacting method must return either
@Command ArchiveTask on(TaskCompleted event) { ... }
Optional
command message:
@Command Optional<StartTask> on(TaskAdded event) { ... }
@Command EitherOf2<StopTask, PauseTask> on(TaskReassigned event) { ... }
Iterable
of command messages:
@Command List<ArchiveTask> on(ProjectCompleted event) { ... }
tuple
of several command messages;
it allows to declare the exact types of returning values, including Optional
s:
@Command Triplet<AssignTask, UpdateTaskDueDate, Optional<StartTask>> on(TaskCreated command) { ... }
If the annotation is applied to a method which doesn't satisfy either of these requirements, this method is not considered a commanding method and is not registered for command generation.
Modifier and Type | Optional Element and Description |
---|---|
boolean |
external
Deprecated.
please use
@External annotation for the first
method parameter. |
@Deprecated public abstract boolean external
@External
annotation for the first
method parameter.true
, the annotated method receives an event generated from outside of the
Bounded Context to which the annotated method's class belongs.
Should only be applied to commanding methods that accept an event or rejection as a parameter.
If applied to a command receiving method, the Model error is produced.