From a95a6318a4bfab534ebf09e13588f6388a4801d7 Mon Sep 17 00:00:00 2001 From: Vasilis Spilka Date: Fri, 18 Jan 2019 15:40:01 +0000 Subject: [PATCH] replace poison with jason --- CHANGELOG.md | 16 +++++++++++++++ config/distributed.exs | 6 +++++- guides/Event Serialization.md | 11 ++++++++++- lib/event_store/json_serializer.ex | 31 ++++++++++++++++++++++++++++++ lib/register_postgres_types.ex | 2 +- mix.exs | 2 +- mix.lock | 1 - test/event_store_test.exs | 5 ++++- test/support/event_factory.ex | 1 + test/support/json_serializer.ex | 27 -------------------------- 10 files changed, 69 insertions(+), 33 deletions(-) create mode 100644 lib/event_store/json_serializer.ex delete mode 100644 test/support/json_serializer.ex diff --git a/CHANGELOG.md b/CHANGELOG.md index bb44263e..f23a3035 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,22 @@ ### Enhancements +- BREAKING CHANGE: Replace `:poison` with `:jason` ([#144](https://github.com/commanded/eventstore/pull/144)). +To support this change the users will need to @derive the Jason.Encoder protocol to all their Events. +This can be done by either using `@derive Jason.Encoder` before defining the struct. Or using `Protocol.derive/2` for each event. +Examples below. +``` +defmodule Event1 do + @derive Jason.Encoder + defstruct [:id, :data] +end +``` +``` +require Protocol +for event <- [Event1, Event2, Event3] do + Protocol.derive(Jason.Encoder, event) +end +``` - Add `:socket` and `:socket_dir` config options ([#132](https://github.com/commanded/eventstore/pull/132)). - Rename `uuid` dependency to `elixir_uuid` ([#135](https://github.com/commanded/eventstore/pull/135)). - Subscription concurrency ([#134](https://github.com/commanded/eventstore/pull/134)). diff --git a/config/distributed.exs b/config/distributed.exs index 9693d2d8..8a706b39 100644 --- a/config/distributed.exs +++ b/config/distributed.exs @@ -1,6 +1,10 @@ use Mix.Config -config :logger, backends: [] +config :logger, + backends: [], + compile_time_purge_matching: [ + [application: :eventstore] + ] config :ex_unit, capture_log: true, diff --git a/guides/Event Serialization.md b/guides/Event Serialization.md index f94b5969..31b248ec 100644 --- a/guides/Event Serialization.md +++ b/guides/Event Serialization.md @@ -4,7 +4,16 @@ The default serialization of event data and metadata uses Erlang's [external ter You must implement the `EventStore.Serializer` behaviour to provide your preferred serialization format. -## Example JSON serializer +## Jason Serializer +EventStore includes a JSON serializer using Jason under the `EventStore.JsonSerializer` module. To include it add `{:jason, "~> 1.1"}` to your dependencies. Then configure EventStore to use it. + +```elixir +config :eventstore, EventStore.Storage, + serializer: EventStore.JsonSerializer, + # ... +``` + +## Example JSON (Poison) serializer The example serializer below serializes event data and metadata to JSON using the [Poison](https://github.com/devinus/poison) library. diff --git a/lib/event_store/json_serializer.ex b/lib/event_store/json_serializer.ex new file mode 100644 index 00000000..44d84e96 --- /dev/null +++ b/lib/event_store/json_serializer.ex @@ -0,0 +1,31 @@ +if Code.ensure_loaded?(Jason) do + defmodule EventStore.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 + Jason.encode!(term) + end + + @doc """ + Deserialize given JSON binary data to the expected type. + """ + def deserialize(binary, config) do + case Keyword.get(config, :type, nil) do + nil -> + Jason.decode!(binary) + + type -> + type + |> String.to_existing_atom() + |> struct(Jason.decode!(binary, keys: :atoms!)) + end + end + end +end diff --git a/lib/register_postgres_types.ex b/lib/register_postgres_types.ex index 24e79876..b3c8d210 100644 --- a/lib/register_postgres_types.ex +++ b/lib/register_postgres_types.ex @@ -1,3 +1,3 @@ if Code.ensure_loaded?(Postgrex) do - Postgrex.Types.define(EventStore.PostgresTypes, [], json: Poison) + Postgrex.Types.define(EventStore.PostgresTypes, [], json: Jason) end diff --git a/mix.exs b/mix.exs index 06a0db8a..dd78559d 100644 --- a/mix.exs +++ b/mix.exs @@ -56,7 +56,7 @@ defmodule EventStore.Mixfile do {:ex_doc, "~> 0.19", only: :dev}, {:markdown, github: "devinus/markdown", only: :dev}, {:mix_test_watch, "~> 0.9", only: :dev}, - {:poison, "~> 2.2 or ~> 3.0", optional: true} + {:jason, "~> 1.1", optional: true} ] end diff --git a/mix.lock b/mix.lock index cd2e7c5d..60e1d925 100644 --- a/mix.lock +++ b/mix.lock @@ -19,7 +19,6 @@ "markdown": {:git, "https://github.com/devinus/markdown.git", "d065dbcc4e242a85ca2516fdadd0082712871fd8", []}, "mix_test_watch": {:hex, :mix_test_watch, "0.9.0", "c72132a6071261893518fa08e121e911c9358713f62794a90c95db59042af375", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm"}, "nimble_parsec": {:hex, :nimble_parsec, "0.5.0", "90e2eca3d0266e5c53f8fbe0079694740b9c91b6747f2b7e3c5d21966bba8300", [:mix], [], "hexpm"}, - "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"}, "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], [], "hexpm"}, "postgrex": {:hex, :postgrex, "0.14.1", "63247d4a5ad6b9de57a0bac5d807e1c32d41e39c04b8a4156a26c63bcd8a2e49", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"}, } diff --git a/test/event_store_test.exs b/test/event_store_test.exs index e27722cc..6cc495a4 100644 --- a/test/event_store_test.exs +++ b/test/event_store_test.exs @@ -330,7 +330,10 @@ defmodule EventStoreTest do end end - defmodule(ExampleData, do: defstruct([:data])) + defmodule ExampleData do + @derive Jason.Encoder + defstruct([:data]) + end test "record snapshot" do assert record_snapshot() != nil diff --git a/test/support/event_factory.ex b/test/support/event_factory.ex index 6f7a2568..acc19cde 100644 --- a/test/support/event_factory.ex +++ b/test/support/event_factory.ex @@ -4,6 +4,7 @@ defmodule EventStore.EventFactory do @serializer Application.get_env(:eventstore, EventStore.Storage)[:serializer] || EventStore.JsonSerializer defmodule Event do + @derive Jason.Encoder defstruct event: nil end diff --git a/test/support/json_serializer.ex b/test/support/json_serializer.ex deleted file mode 100644 index 1588d4cf..00000000 --- a/test/support/json_serializer.ex +++ /dev/null @@ -1,27 +0,0 @@ -defmodule EventStore.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