View Source Upgrade guide v0.17.x to v1.0

In v0.17.x and earlier EventStore was a singleton application with all functionality exposed by the EventStore module. To support multiple event stores in a single Elixir application you must now define your own event store module using the EventStore macro. You can define as many event stores as you like, each one is isolated and can be configured to use its own Postgres database.

Getting started

First, you must define your own event store module using the EventStore macro:

# lib/my_app/event_store.ex
defmodule MyApp.EventStore do
  use EventStore, otp_app: :my_app

  # Optional `init/1` function to modify config at runtime.
  def init(config) do
    {:ok, config}
  end
end

You can name your event store module however you like and optionally implement an init/1 callback function.

Secondly, configure the MyApp.EventStore module (in config/config.exs or each environment's config):

config :my_app, MyApp.EventStore,
  serializer: EventStore.JsonSerializer,
  username: "postgres",
  password: "postgres",
  database: "myapp_eventstore",
  hostname: "localhost",
  pool_size: 10

Note: To use an EventStore with Commanded you should configure the event store to use Commanded's JSON serializer which provides additional support for JSON decoding:

config :my_app, MyApp.EventStore, serializer: Commanded.Serialization.JsonSerializer

Finally, the event store module must be included within your application's supervision tree, inside the start/2 function:

# lib/my_app/application.ex
defmodule MyApp.Application do
  use Application

  def start(_type, _args) do
    children = [
      MyApp.EventStore
    ]

    opts = [strategy: :one_for_one, name: MyApp.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

Optionally, you can configure the event store modules in config/config.exs to allow running the event store mix tasks without providing the event store module as a command line argument:

config :my_app, event_stores: [MyApp.EventStore]

The above configuration allows you to run mix event_store.init instead of mix event_store.init -e MyApp.EventStore (as an example).

Usage

Use your event store module exactly as you would have previously used the EventStore itself.

:ok = MyApp.EventStore.append_to_stream(stream_uuid, expected_version, events)

For ease of upgrading you can alias your own event store module as EventStore allowing you to use it without making any further code changes:

alias MyApp.EventStore, as: EventStore

:ok = EventStore.append_to_stream(stream_uuid, expected_version, events)