Home

Awesome

Helios.Aggregate

Elixir library defining Aggregate behaviour and providing extendable facility for aggregate command pipeline.

Please note this package is not full CQRS framework. We strongly disagree that CQRS can be boxed into framewrok, it is rather set of techniques you CAN apply to your service architecture.

Installation

Available in Hex, the package can be installed by adding helios_aggregate to your list of dependencies in mix.exs:

def deps do
  [
    {:helios_aggregate, "~> 0.1"}
  ]
end

Aggregate example

defmodule Customer do
  use Helios.Aggregate

  # Aggregate state
  defstruct [:first_name, :last_name, :email]

  # Events emitted by aggregate
  defmodule CustomerCreated, do: defstruct [:id, :first_name, :last_name]
  defmodule CustomerContactCreated, do: defstruct [:email]

  def create(ctx, %{first_name: first_name, last_name: last_name, email: email}) do
    
    ctx
    |> emit_event(%CustomerCreated{first_name: first_name, last_name: last_name})
    |> emit_event(%CustomerContactCreated{email: email})
  end

  def apply_event(customer, %CustomerCreated{}=event) do
    %{customer|
      first_name: event.first_name,
      last_name: event.last_name
    }
  end

  def apply_event(customer, %CustomerContactCreated{email: email}) do
    %{customer| email: email}
  end
end
  ctx = %Helios.Aggregate.Pipeline.Context{
    aggregate: %Helix.Aggregate{state: },
    aggregate_module: CustomerAggregate,
    correlation_id: "1234567890",
    command: :create_user,
    peer: self(),
    params: %{first_name: "Jhon", last_name: "Doe", email: "jhon.doe@gmail.com"}
  }

  Cusomer.call(ctx, :create)
    

Logger configuration

We build logger which should log each command sent to aggregate. Since commands can cary some confidential information, or you have to be PCI DSS compliant, we expsed configuration like below where you could configure which filed values in command should be retracted.

Below is example where list of field names are given. Please note, the logger plug will not try to conver string to atom or other way round, if you have both case please state them in list as both, string and atom.

use Mix.Config

# filter only specified
config :helios_aggregate, 
  :filter_parameters, [:password, "password", :credit_card_number]

# filter all but keep original values
config :helios_aggregate, 
  :filter_parameters, {:keep, [:email, "email", :full_name]}

# retract only specified field values
config :helios_aggregate, 
  :filter_parameters, [:password, "password", :credit_card_number]


Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/helios_aggregate.