On the Aggregates section we learned how to design an
Aggregate in terms of
Command Handlers and
Event Handlers. However, we still don’t have the means to work with it.
To understand the role of a backend we must first go back to the basic CQRS/ES operations that we are trying to abstract over. In CQRS/ES we can devise two basic functions:
// basic Command Handler (State[Aggregate], Command) => F[Events] // basic Event Handler (State[Aggregate], Event) => State[Aggregate]
Note: in Fun.CQRS we don’t directly define functions like those. Instead we use the Behavior DSL that allow us to define them by concentrate only on the parts that are domain specific.
Command Handler receives the state of an
Aggregate and a new
Command and emits one or more
Events are wrapped on a
F[_] can be any of:
Event Handler receives the state of an
Aggregate and an
Event and produces a new
Given those two functions, the role of the backend is:
- Provide the current
- Understand how to deal with
F[_]and “interpret” it
- Persist the
Eventseventually emitted by the
- Update the current
State[Aggregate]by applying the emitted
As such, a Fun.CQRS backend is where IO and persistence take place.
A backend is also tight to a
F[_] and will lift all possible incarnations of
F[_] to its own
F[_]. For instance, for the
F is as
Future. If you define a
Command Handler that returns a
Try and use it with the
AkkaBackend, you will get a
More over, a backend does not let you work directly with an
Aggregate. The principle is pretty much inspired in Akka. You request an
AggregateRef, you send
Commands to it and you don’t manipulate the
In orde to use an
Aggregate we must first configure it on a Backend. This is done only once and is supposed to happen when bootstrapping the application.
(we see how to configure it on tutorial section: Command Side Tests)
Once the aggregate is configured we can ask the backend for instances of
AggregateRef to work with.
Similar to Akka, we don’t work directly with an
Aggregate, but with a reference to it. The
Aggregate itself lives inside the backend and we send commands to each via an
ask (?) and
tell (!). Again shameless inspired by Akka.
The only difference is that an
AggregateRef can only receive commands previously defined by its
Protocol and will only emit
Events from its
Protocol as well. As such, an
AggregateRef is typed on its
For test purposes we provide a
Aggregate state are ‘persisted’ in-memory.
Identity can NOT express an error condition and therefore it will block for
Command Handlers returning
Futures and it will throw exceptions for failed
A usage example for the
InMemoryBackend can be found on tutorial section on Command Side Tests
AkkaBackend is intended for production use and defines
Aggregate lives inside an
PersistentActor and the backend guarantees that at most one instance (per
AggregateId) is loaded in-memory.
Events are persisted using akka-persistence.
Detailed documentation about the
AkkaBackend can be found here