Forwarding and effects in JavaScript

A command can only act on one Entity at a time—​the Entity that received the command. For certain use cases, you might want a different Entity to handle the command. Rather than sending an immediate reply to a command, the receiving Entity can forward the command to another Entity. In cases where you simply want other Entities to be aware that an Entity processed a command, you can emit an effect.

You handle forwarding or emit effects in the receiving Entity’s command handler. The forwarding or effect can target any Entity within the service—​whether it is an instance of the same or different Entity type.

Transactional limitations

It’s important to note that forwarded commands, and commands emitted as side effects, are non-atomic—​there is no guarantee that the transactions either all succeeded or none. If the service, or the data store, fails while a forwarded command is executing, the original command that triggered it will not be rolled back.

If partial updates will cause problems, you should not use forwarding and effects to update multiple Entities at once.

Forwarding control to another Entity

To forward a command, you send a forward message that includes the call to invoke, and the message to invoke it with. The command won’t be forwarded until any state actions requested by the command handler have successfully completed. It is the responsibility of the forwarded action to return a reply that matches the type of the original command handler. Forwards can be chained arbitrarily long.

You might want to forward control, for example, from an Entity that processes an event stream. Events are associated with a particular Entity ID. Entities that process an event stream from a remote topic or from another event sourced Entity might have reason to update an Entity that did not receive the events. In this case, the command handler should extract the original Entity ID, and then forward the command to the target Entity.

Emitting effects on another Entity

An Entity may also emit one or more effects. An effect is something whose result has no impact on the result of the current command—​if it fails, the current command still succeeds. The result of the effect is therefore ignored. Effects are only performed after the successful completion of any state actions requested by the command handler.

Effects may be declared as synchronous or asynchronous. Asynchronous commands run in a "fire and forget" fashion. The code flow of the caller (the command handler of the Entity which emitted the asynchronous command) continues while the command is being asynchronously processed. Meanwhile, synchronous commands run in "blocking" mode, that is, the commands are processed in order, one at a time. The final result of the command handler, either a reply or a forward, is not sent until all synchronous commands are completed.

You might want to emit effects to notify interested parties of a change in state. For example, after a withdrawal is made from a bank account, an account Entity could send a notification to the account owner’s mobile phone.

Language support

For detailed documentation on implementing forwarding and effects in your favourite language, follow the links below:

Forwarding a command

The CommandContextnew tab can call the method thenForwardnew tab to forward the command to another entity service call.

Emitting an effect

The CommandContextnew tab for each entity type implements EffectContextnew tab, which is able to emit an effect after processing the command by invoking the method effectnew tab