commanded v0.18.0 Release Notes

Release Date: 2019-01-23 // about 1 year ago
  • ✨ Enhancements

    • 📇 Rename uuid dependency to elixir_uuid (#178).
    • 👍 Allow aggregate identity to be of any type that implements the String.Chars protocol (#166).
    • 👻 Process manager and event handler error & exception handling (#192).
    • ⏱ Process manager event handling timeout (#193).
    • 👍 Allow event handlers to subscribe to individual streams (#203).
    • ➕ Add new values for expected_version for event store append events behaviour (#127).
    • Export Commanded.Commands.Router macros in .formatter.exs file (#204).
    • 📄 Generate specs and docs for Router dispatch functions only once (#206).
    • Allow two-arity predicate function in wait_for_event receiving both event data and recorded event struct (#213).
    • 👍 Allow :infinity timeout on command dispatch (#227)
    • Strict process manager routing (#243).
    • 👍 Allow Commanded.Aggregate.Multi to be nested (#244).
    • ➕ Add child_spec/0 function to Commanded.EventStore behaviour.
    • ➕ Add delete_subscription/2 to Commanded.EventStore behaviour (#245).
    • Add refute_receive_event/2 to Commanded.Assertions.EventAssertions test helpers.

    🐛 Bug fixes

    • Fix typo in include_execution_result global router option (#216).
    • 🖐 Handle the {:ok, _} tuple dispatch result in process manager command dispatch (#236).
    • 👍 Allow string keys for Commanded.Middleware.Pipeline.assign_metadata/3, atoms are being deprecated (#228)
    • 🛠 Fix Commanded.PubSub.subscribe/1 typespec (#222).

    💥 Breaking changes

    • 📦 Migrate to Jason for JSON serialization (#234).

    You will need to add Jason as a dependency in mix.exs:

      defp deps do
        [{:jason, "~> 1.1"}]
      end
    

    Jason has no support for encoding arbitrary structs - explicit implementation of the Jason.Encoder protocol is always required. You must update all your domain event modules, aggregate state (when using state snapshotting), and process manager state to include @derive Jason.Encoder as shown below:

      defmodule AnEvent do
        @derive Jason.Encoder
        defstruct [:field]
      end
    
    • Extend aggregate lifespan behaviour to include after_error/1 and after_command/1 callbacks (#210).

    Previously you only had to define an after_event/1 callback function to implement the Commanded.Aggregates.AggregateLifespan behaviour:

      defmodule BankAccountLifespan do
        @behaviour Commanded.Aggregates.AggregateLifespan
    
        def after_event(%BankAccountClosed{}), do: :stop
        def after_event(_event), do: :infinity
      end
    

    Now you must also define after_command/1 and after_error/1 callback functions:

      defmodule BankAccountLifespan do
        @behaviour Commanded.Aggregates.AggregateLifespan
    
        def after_event(%BankAccountClosed{}), do: :stop
        def after_event(_event), do: :infinity
    
        def after_command(%CloseAccount{}), do: :stop
        def after_command(_command), do: :infinity
    
        def after_error(:invalid_initial_balance), do: :stop
        def after_error(_error), do: :stop
      end
    

    ⬆️ Upgrading

    ⬆️ Please ensure you upgrade the following event store dependencies.

    Using the Elixir EventStore:

    • 📦 eventstore to v0.16.0
    • commanded_eventstore_adapter to v0.5.0

    Using Greg Young's Event Store:

    • commanded_extreme_adapter to v0.6.0

    Commanded Ecto projections:

    • commanded_ecto_projections to v0.8.0

    ⏱ Commanded scheduler:

    • commanded_scheduler to v0.2.0