Current section
Files
Jump to
Current section
Files
README.md
# JasonA blazing fast JSON parser and generator in pure Elixir.The parser and generator are at least twice as fast as other Elixir/Erlang libraries(most notably `Poison`).The performance is comparable to `jiffy`, which is implemented in C as a NIF.Jason is usually only twice as slow.Both parser and generator fully conform to[RFC 8259](https://tools.ietf.org/html/rfc8259) and[ECMA 404](http://www.ecma-international.org/publications/standards/Ecma-404.htm)standards. The parser is tested using [JSONTestSuite](https://github.com/nst/JSONTestSuite).## InstallationThe package can be installed by adding `jason` to your list of dependenciesin `mix.exs`:```elixirdef deps do [{:jason, "~> 1.4"}]end```## Basic Usage``` elixiriex(1)> Jason.encode!(%{"age" => 44, "name" => "Steve Irwin", "nationality" => "Australian"})"{\"age\":44,\"name\":\"Steve Irwin\",\"nationality\":\"Australian\"}"iex(2)> Jason.decode!(~s({"age":44,"name":"Steve Irwin","nationality":"Australian"}))%{"age" => 44, "name" => "Steve Irwin", "nationality" => "Australian"}```Full documentation can be found at [https://hexdocs.pm/jason](https://hexdocs.pm/jason).## Use with other libraries### PostgrexVersions starting at 0.14.0 use `Jason` by default. For earlier versions, please refer to[previous versions of this document](https://github.com/michalmuskala/jason/tree/v1.1.2#postgrex).### EctoVersions starting at 3.0.0 use `Jason` by default. For earlier versions, please refer to[previous versions of this document](https://github.com/michalmuskala/jason/tree/v1.1.2#ecto).### Plug (and Phoenix)Phoenix starting at 1.4.0 uses `Jason` by default. For earlier versions, please refer to[previous versions of this document](https://github.com/michalmuskala/jason/tree/v1.1.2#plug-and-phoenix).### AbsintheYou need to pass the `:json_codec` option to `Absinthe.Plug````elixir# When called directly:plug Absinthe.Plug, schema: MyApp.Schema, json_codec: Jason# When used in phoenix router:forward "/api", to: Absinthe.Plug, init_opts: [schema: MyApp.Schema, json_codec: Jason]```## BenchmarksDetailed benchmarks (including memory measurements):https://gist.github.com/michalmuskala/4d64a5a7696ca84ac7c169a0206640d5HTML reports for the benchmark (only performance measurements):http://michal.muskala.eu/jason/decode.html and http://michal.muskala.eu/jason/encode.html### RunningBenchmarks against most popular Elixir & Erlang json libraries can be executed aftergoing into the `bench/` folder and then executing `mix bench.encode` and `mix bench.decode`.A HTML report of the benchmarks (after their execution) can be found in`bench/output/encode.html` and `bench/output/decode.html` respectively.## Differences to PoisonJason has a couple feature differences compared to Poison. * Jason follows the JSON spec more strictly, for example it does not allow unescaped newline characters in JSON strings - e.g. `"\"\n\""` will produce a decoding error. * no support for decoding into data structures (the `as:` option). * no built-in encoders for `MapSet`, `Range` and `Stream`. * no support for encoding arbitrary structs - explicit implementation of the `Jason.Encoder` protocol is always required. * different pretty-printing customisation options (default `pretty: true` works the same)### EncodersIf you require encoders for any of the unsupported collection types, I suggestadding the needed implementations directly to your project:```elixirdefimpl Jason.Encoder, for: [MapSet, Range, Stream] do def encode(struct, opts) do Jason.Encode.list(Enum.to_list(struct), opts) endend```If you need to encode some struct that does not implement the protocol,if you own the struct, you can derive the implementation specifyingwhich fields should be encoded to JSON:```elixir@derive {Jason.Encoder, only: [....]}defstruct # ...```It is also possible to encode all fields, although this should beused carefully to avoid accidentally leaking private informationwhen new fields are added:```elixir@derive Jason.Encoderdefstruct # ...```Finally, if you don't own the struct you want to encode to JSON,you may use `Protocol.derive/3` placed outside of any module:```elixirProtocol.derive(Jason.Encoder, NameOfTheStruct, only: [...])Protocol.derive(Jason.Encoder, NameOfTheStruct)```## Injecting an already encoded JSON inside a to-be-encoded structureIf parts of the to-be-encoded structure are already JSON-encoded, you canuse `Jason.Fragment` to mark the parts as already encoded, and avoid adecoding/encoding roundtrip.```elixiralready_encoded_json = Jason.encode!(%{hello: "world"})Jason.encode!(%{foo: Jason.Fragment.new(already_encoded_json)})```This feature is especially useful if you need to cache a part of the JSON,or if it is already provided by another system (e.g. `jsonb_agg` with Postgres).## LicenseJason is released under the Apache License 2.0 - see the [LICENSE](LICENSE) file.Some elements of tests and benchmarks have their origins in the[Poison library](https://github.com/devinus/poison) and were initially licensed under [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/).