Poisonならdecode
の際にキーをatomに変換するkeys: :atoms!
オプションを使うといいでしょう。
elixir
1iex> map = %{key1: "value1", key2: "value2"}
2%{key1: "value1", key2: "value2"}
3
4# mapをjson文字列に変換する
5iex> json = Poison.encode!(map)
6"{\"key2\":\"value2\",\"key1\":\"value1\"}"
7
8# json文字列をmapに変換する。その際、キーはatomにする
9iex> Poison.decode!(json, %{keys: :atoms!})
10%{key1: "value1", key2: "value2"}
別の方法として、JSONではなく、Erlang組み込みのシリアライズフォーマットであるErlang external term formatを使うこともできます。
JSON(JavaScript Object Notion)は元々はJavaScriptのオブジェクトをシリアライズするために考案されたフォーマットですので、ErlangやElixirのatomのようなJavaScriptにはないデータ型は表現できません。Erlangは分散システムの開発が得意な言語ですので、ノード間でErlangのデータ(Erlang termと呼ばれます)を送受信するための専用のシリアライズフォーマットが昔から言語に組み込まれています。このフォーマットならmapだけでなく、atomなども表現できます。
ただし、JSONは人間が直接読めるフォーマットですが、Erlang external term formatはbinary(バイト列)なので人間には読めません。その代わり、全てのErlang termが表現できます。
elixir
1iex> map = %{key1: "value1", key2: "value2"}
2%{key1: "value1", key2: "value2"}
3
4# Erlang termをシリアライズする
5iex> bin = :erlang.term_to_binary(map)
6<<131, 116, 0, 0, 0, 2, 100, 0, 4, 107, 101, 121, 49, 109, 0, 0, 0, 6, 118, 97,
7 108, 117, 101, 49, 100, 0, 4, 107, 101, 121, 50, 109, 0, 0, 0, 6, 118, 97,
8 108, 117, 101, 50>>
9
10# Erlang termをデシリアライズする
11iex> :erlang.binary_to_term(bin)
12%{key1: "value1", key2: "value2"}
13
14# binaryを印字可能な文字に変換するにはBase.encode16が使える
15iex> encoded = Base.encode16(bin)
16"8374000000026400046B6579316D0000000676616C7565316400046B6579326D0000000676616C756532"
17
18iex> Base.decode16(encoded)
19{:ok,
20 <<131, 116, 0, 0, 0, 2, 100, 0, 4, 107, 101, 121, 49, 109, 0, 0, 0, 6, 118, 97,
21 108, 117, 101, 49, 100, 0, 4, 107, 101, 121, 50, 109, 0, 0, 0, 6, 118, 97,
22 108, 117, 101, 50>>}
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。