Event serialization

The default serialization of event data and metadata uses Erlang's external term format. This is not a recommended serialization format for production usage as backwards compatibility is only guaranteed going back at least two major releases.

You must implement the EventStore.Serializer behaviour to provide your preferred serialization format.

JSON serialization using Jason

EventStore includes a JSON serializer using Jason in the EventStore.JsonSerializer module. To include it, add {:jason, "~> 1.1"} to your application's mix dependencies and configure your EventStore as below.

config :eventstore, MyApp.EventStore, serializer: EventStore.JsonSerializer

Example JSON serializer using Poison

The example serializer below serializes event data and metadata to JSON using the Poison library.

defmodule JsonSerializer do
  @moduledoc """
  A serializer that uses the JSON format.
  """

  @behaviour EventStore.Serializer

  @doc """
  Serialize given term to JSON binary data.
  """
  def serialize(term) do
    Poison.encode!(term)
  end

  @doc """
  Deserialize given JSON binary data to the expected type.
  """
  def deserialize(binary, config) do
    type = case Keyword.get(config, :type, nil) do
      nil -> []
      type -> type |> String.to_existing_atom |> struct
    end
    Poison.decode!(binary, as: type)
  end
end

Configure the JSON serializer for your event store by setting the serializer option in the mix environment configuration file (e.g. config/dev.exs):

config :eventstore, MyApp.EventStore, serializer: JsonSerializer

You must set the event_type field to a string representing the type of event being persisted when using this serializer:

%EventStore.EventData{
  event_type: "Elixir.ExampleEvent",
  data: %ExampleEvent{key: "value"},
  metadata: %{user: "someuser@example.com"},
}

You can use Atom.to_string/1 to get a string representation of a given event struct compatible with the example JsonSerializer module:

event = %ExampleEvent{key: "value"}
event_type = Atom.to_string(event.__struct__)  #=> "Elixir.ExampleEvent"