Getting started
EventStore is available in Hex and can be installed as follows:
Add eventstore to your list of dependencies in
mix.exs
:def deps do [{:eventstore, "~> 1.0"}] end
Run
mix deps.get
to install the new dependency.Define an event store module for your application:
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
Add a config entry containing the PostgreSQL database connection details for your event store module to each environment's mix config file (e.g.
config/dev.exs
):config :my_app, MyApp.EventStore, serializer: EventStore.JsonSerializer, username: "postgres", password: "postgres", database: "eventstore", hostname: "localhost" # OR use a URL to connect instead config :my_app, MyApp.EventStore, serializer: EventStore.JsonSerializer, url: "postgres://postgres:postgres@localhost/eventstore"
Configure optional database connection settings:
config :my_app, MyApp.EventStore, pool_size: 10 pool_overflow: 5 queue_target: 50 queue_interval: 1_000
The database connection pool configuration options are:
:pool_size
- The number of connections (default:10
).:pool_overflow
- The maximum number of overflow connections to start if all connections are checked out (default:0
).
Handling requests is done through a queue. When DBConnection is started, there are two relevant options to control the queue:
:queue_target
- in milliseconds (default: 50ms).:queue_interval
- in milliseconds (default: 1,000ms).
Add your event store module to the
event_stores
list for your app in mix config:# config/config.exs config :my_app, event_stores: [MyApp.EventStore]
This ensures the event store mix tasks can be run without specifying the event store as a command line argument (e.g.
mix event_store.init -e MyApp.EventStore
).Create and initialize the event store database and tables using the
mix
tasks:$ mix do event_store.create, event_store.init
The final piece of configuration is to setup your event store as a supervisor within your application's supervision tree (e.g. in
lib/my_app/application.ex
, inside thestart/2
function):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
Using an existing database
You can use an existing PostgreSQL database with EventStore by running the following mix
task to create and initialize the event store tables:
$ mix event_store.init
Reset an existing database
To drop an existing EventStore database and recreate it you can run the following mix
tasks:
$ mix do event_store.drop, event_store.create, event_store.init
Warning this will delete all EventStore data.
Initialize a database using a Elixir releases
If you're using an Elixir release build by the task mix release you won't have mix
available therefore you won't be able to run the following command in order to initialize a new database.
$ mix do event_store.create, event_store.init
To do that you can use task modules defined inside EventStore (in lib/mix/tasks
):
So you can take advantage of the running one-off commands supported by Mix release, using a helper module defined like this:
defmodule MyApp.ReleaseTasks do
def init_event_store do
{:ok, _} = Application.ensure_all_started(:postgrex)
{:ok, _} = Application.ensure_all_started(:ssl)
:ok = Application.load(:eventstore)
config = EventStore.Config.parsed()
:ok = EventStore.Tasks.Create.exec(config, [])
:ok = EventStore.Tasks.Init.exec(config, [])
end
end
Event data and metadata data type
EventStore has support for persisting event data and metadata as either:
- Binary data, using the
bytea
data type, designed for storing binary strings. - JSON data, using the
jsonb
data type, specifically designed for storing JSON encoded data.
The default data type is bytea
. This can be used with any binary serializer, such as the Erlang Term format, JSON data encoded to binary, and other serialization formats.
Using the jsonb
data type
The advantage this format is that it allows you to execute ad-hoc SQL queries against the event data or metadata using PostgreSQL's native JSON query support.
To enable native JSON support you need to configure your event store to use the jsonb
data type. You must also use the EventStore.JsonbSerializer
serializer, to ensure event data and metadata is correctly serialized to JSON, and include the Postgres types module (EventStore.PostgresTypes
) for the Postgrex library to support JSON.
# config/config.exs
config :my_app, MyApp.EventStore,
column_data_type: "jsonb"
serializer: EventStore.JsonbSerializer,
types: EventStore.PostgresTypes
Finally, you need to include the Jason library as a depencency in mix.exs
to enable Postgrex JSON support and then run mix deps.get
to install.
# mix.exs
defp deps do
[{:jason, "~> 1.1"}]
end
These settings must be configured before creating the EventStore database. It's not possible to migrate between bytea
and jsonb
data types once you've created the database. This must be decided in advance.