Disco v0.1.3 Disco.Command behaviour View Source

The command specification.

A command in Disco is a struct which has the fields representing potential parameters for the command itself.

This module defines a behaviour with a set of default callback implementations to execute a command on an aggregate.

Define a command

Here’s how to implement a simple command without params:

defmodule MyApp.DoSomething do
  use Disco.Command

  def run(%__MODULE__{} = _command, state) do
    [%{type: "SomethingDone", ...}]
  end
end

If you might need some params:

defmodule MyApp.DoSomethingWithParams do
  use Disco.Command, foo: nil

  def run(%__MODULE__{} = command, state), do
    [%{type: "SomethingDone", ...}]
  end
end

It’s also possible to apply validations on the params. Refer to Vex for more details.

defmodule MyApp.DoSomethingWithValidations do
  use Disco.Command, foo: nil, bar: nil

  # param `foo` is required, `bar` isn't.
  validates(:foo, presence: true)

  def run(%__MODULE__{} = command, state), do
    [%{type: "SomethingDone", aggregate_id: "123",...}]
  end
end

Overriding default functions

As you can see, the simplest implementation only requires to implement run/2 callback, while the others are already implemented by default. Sometimes you might need a custom initialization or validation function, that’s why it’s possible to override new/1 and validate/1.

Usage example

NOTE: Disco.Factories.ExampleCommand has been defined in test/support/examples/example_command.ex.

iex> alias Disco.Factories.ExampleCommand, as: Cmd
iex> Cmd.new(%{foo: "bar"}) == %Cmd{foo: "bar"}
true
iex> Cmd.new(%{foo: "bar"}) |> Cmd.validate()
{:ok, %ExampleCommand{foo: "bar"}}
iex> Cmd.new() |> Cmd.validate()
{:error, %{foo: ["must be present"]}}
iex> Cmd.run(%Cmd{foo: "bar"})
[%{type: "FooHappened", aggregate_id: _, foo: "bar"}]

Link to this section Summary

Functions

Defines the struct fields and the default callbacks to implement the behaviour to run a command

Builds an event map

Callbacks

Called to init, validate and run the command all at once

Called to initialize a command

Called to run the command

Called to validate the command

Link to this section Types

Link to this type error() View Source
error() :: {:error, %{optional(atom()) => [binary()]} | binary()}

Link to this section Functions

Link to this macro __using__(attrs) View Source (macro)

Defines the struct fields and the default callbacks to implement the behaviour to run a command.

Options

The only argument accepted is a Keyword list of fields for the command struct.

Link to this function build_event(type, payload, state) View Source
build_event(type :: binary(), payload :: map(), state :: map()) ::
  event :: map()

Builds an event map.

Link to this section Callbacks

Link to this callback execute(map) View Source
execute(map()) :: any()

Called to init, validate and run the command all at once.

Link to this callback new(command) View Source
new(command :: map()) :: map()

Called to initialize a command.

Link to this callback run(command, state) View Source
run(command :: map() | error(), state :: map()) :: [event :: map()] | error()

Called to run the command.

Link to this callback validate(command) View Source
validate(command :: map()) :: {:ok, map()} | error()

Called to validate the command.