Fable. Events behaviour
(Fable v0.0.1-alpha.2)
View Source
Fable.Events is the repository for Fable.Events.
When used it expects a :repo key to be set as an option:
defmodule MyApp.Events do
use Fable.Events, repo: MyApp.Repo
endOptions
:registry- The name of the registry used for the process managers. Defaults toFable.+ repo name:router- The module responsible for defining the routing of events. Defaults to__MODULE__to their handlers:event_schema- The schema to be used for persisting events. Defaults toFable.Event:process_manager_schema- The schema to be used for persisting process managers' state. Defaults toFable.ProcessManager.State:json_library- The library used for json encoding. Defaults toJason
Emitting events
You can emit events as a standalone action or as part of an
Ecto.Multi pipeline. For both ways you need to pass the resulting term
to Repo.transaction for it to be applied.
Standalone action:
def create_aggregate(user, args) do
%MyApp.Aggregate{id: uuid}
|> MyApp.Events.emit(fn aggregate, repo, _changes ->
with {:ok, _} <- can(user, :create_aggregate) do
%MyApp.Aggregate.Created{args: args, user: user}
end
end)
|> Repo.transaction
endAs part of Ecto.Multi:
def create_child_on_aggregate(aggregate, user, args) do
multi =
Ecto.Multi.new
|> MyApp.Events.emit(aggregate, :aggregate, fn aggregate, repo, _changes ->
with {:ok, _} <- can(user, :create_child) do
%MyApp.Aggregate.ChildCreated{args: args, user: user}
end
end)
|> Ecto.Multi.run(:child, fn repo, %{aggregate: aggregate} ->
get_latest_child(aggregate, repo)
end)
case Repo.transaction(multi) do
{:ok, %{child: child}} -> {:ok, child}
{:error, :aggregate, error, _} -> {:error, error}
end
endHandling events
By default MyApp.Events will also be your router module. Look at Fable.Router
for more information on that.
Summary
Callbacks
Creates a function, which emits events for an aggregate when passed to Repo.transaction.
Emit events as step within an Ecto.Multi pipeline.
Lists all the events of the aggregate in order.
Delete the given aggregate and replay all its events, building a new aggregate.
Types
@type emit_callback() :: (Ecto.Schema.t(), Ecto.Repo.t() -> event_or_events()) | (Ecto.Schema.t(), Ecto.Repo.t(), Ecto.Multi.changes() -> event_or_events())
@type event_or_events() :: Fable.Event.t() | [Fable.Event.t()]
@type handler() :: (Fable.aggregate(), Fable.Event.t() -> {:ok, Fable.aggregate()} | {:error, term()})
@type transation_fun() :: (Ecto.Repo.t() -> any())
Callbacks
@callback emit(Fable.aggregate(), emit_callback(), Keyword.t()) :: transation_fun()
Creates a function, which emits events for an aggregate when passed to Repo.transaction.
@callback emit( Ecto.Multi.t(), Fable.aggregate(), Ecto.Multi.name(), emit_callback(), Keyword.t() ) :: Ecto.Multi.t()
Emit events as step within an Ecto.Multi pipeline.
@callback log(Fable.aggregate()) :: [Fable.Event.t()]
Lists all the events of the aggregate in order.
@callback replay(repo :: Ecto.Repo.t(), Fable.aggregate()) :: {:ok, Fable.aggregate()} | {:error, term()}
Delete the given aggregate and replay all its events, building a new aggregate.