JSON encoding and decoding.
Both encoder and decoder fully conform to RFC 8259 and ECMA 404 standards.
Elixir built-in data structures are encoded to JSON as follows:
| Elixir | JSON |
|---|---|
integer() | float() |
Number |
true | false |
Boolean |
nil |
Null |
binary() |
String |
atom() |
String |
list() |
Array |
%{binary() => _} |
Object |
%{atom() => _} |
Object |
%{integer() => _} |
Object |
You may also implement the JSON.Encoder protocol for custom data structures.
Elixir built-in data structures are decoded from JSON as follows:
| JSON | Elixir |
|---|---|
| Number | integer() | float() |
| Boolean | true | false |
| Null | nil |
| String | binary() |
| Object | %{binary() => _} |
Decodes the given JSON.
Decodes the given JSON with the given decoders.
Decodes the given JSON but raises an exception in case of errors.
Encodes the given term to JSON as a binary.
Encodes the given term to JSON as an iodata.
This is the default encode implementation passed to encode!/1.
@spec decode(binary()) :: {:ok, term()} | {:error, decode_error_reason()} Decodes the given JSON.
Returns {:ok, decoded} or {:error, reason}.
iex> JSON.decode("[null,123,\"string\",{\"key\":\"value\"}]")
{:ok, [nil, 123, "string", %{"key" => "value"}]}
The error tuple will have one of the following reasons.
{:unexpected_end, offset} if binary contains incomplete JSON value{:invalid_byte, offset, byte} if binary contains unexpected byte or invalid UTF-8 byte{:unexpected_sequence, offset, bytes} if binary contains invalid UTF-8 escape@spec decode(binary(), term(), keyword()) ::
{term(), term(), binary()} | {:error, decode_error_reason()} Decodes the given JSON with the given decoders.
Returns {decoded, acc, rest} or {:error, reason}. See decode/1 for the error reasons.
All decoders are optional. If not provided, they will fall back to implementations used by the decode/1 function:
array_start: fn _ -> [] end
for array_push: fn elem, acc -> [elem | acc] end
array_finish: fn acc, old_acc -> {Enum.reverse(acc), old_acc} end
object_start: fn _ -> [] end
for object_push: fn key, value, acc -> [{key, value} | acc] end
object_finish: fn acc, old_acc -> {Map.new(acc), old_acc} end
float: &String.to_float/1
integer: &String.to_integer/1
string: &Function.identity/1
null: the atom nil
For streaming decoding, see Erlang's :json module.
@spec decode!(binary()) :: term()
Decodes the given JSON but raises an exception in case of errors.
Returns the decoded content. See decode/1 for possible errors.
iex> JSON.decode!("[null,123,\"string\",{\"key\":\"value\"}]")
[nil, 123, "string", %{"key" => "value"}] @spec encode!(term(), encoder()) :: binary()
Encodes the given term to JSON as a binary.
The second argument is a function that is recursively invoked to encode a term.
If you need to encode data to be sent over the network or written to the filesystem, consider using the more efficient encode_to_iodata!/2.
iex> JSON.encode!([123, "string", %{key: "value"}])
"[123,\"string\",{\"key\":\"value\"}]" @spec encode_to_iodata!(term(), encoder()) :: iodata()
Encodes the given term to JSON as an iodata.
This is the most efficient format if the JSON is going to be used for IO purposes.
The second argument is a function that is recursively invoked to encode a term.
iex> data = JSON.encode_to_iodata!([123, "string", %{key: "value"}])
iex> IO.iodata_to_binary(data)
"[123,\"string\",{\"key\":\"value\"}]" @spec protocol_encode(term(), encoder()) :: iodata()
This is the default encode implementation passed to encode!/1.
This function is most typically passed as second argument to encode!/2 and encode_to_iodata!/2. The default implementation is an optimized dispatch to the JSON.Encoder protocol.
© 2012-2024 The Elixir Team
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.18.1/JSON.html