diff --git a/README.md b/README.md index 62d7863..55723e8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ # njson + +> **Archived**: This library is no longer maintained. Since OTP 27, the `json` module is included in the standard library and covers the same functionality. We recommend migrating to `json` for all new and existing projects. See the [Migration Guide](#migrating-to-otp-json) below. + [![njson](https://github.com/nomasystems/njson/actions/workflows/ci.yml/badge.svg)](https://github.com/nomasystems/njson/actions/workflows/ci.yml) `njson` is a robust and efficient Erlang library that seamlessly encodes and decodes JSON @@ -103,6 +106,95 @@ Encoder: -------------------------------------------------------------------------------------- ``` +## Migrating to OTP json + +OTP 27 introduced the `json` module, which provides native JSON encoding and decoding. This section covers the key differences and common pitfalls when migrating from `njson`. + +### Decoding + +`njson:decode/1` returns `{ok, Term}` or `{error, Reason}`. `json:decode/1` returns the term directly and throws on invalid input. + +```erl +%% njson +{ok, Map} = njson:decode(Binary). + +%% json +Map = json:decode(Binary). +``` + +If you relied on `{error, _}` to handle invalid JSON, wrap the call in a try-catch: + +```erl +%% njson +case njson:decode(Binary) of + {ok, Map} -> handle(Map); + {error, _} -> handle_error() +end. + +%% json +try json:decode(Binary) of + Map -> handle(Map) +catch + _:_ -> handle_error() +end. +``` + +### Encoding + +`njson:encode/1` returns `{ok, Binary}`. `json:encode/1` returns **iodata** (not a binary). + +```erl +%% njson +{ok, Binary} = njson:encode(Map). + +%% json (returns iodata) +IoData = json:encode(Map). +``` + +If you need a `binary()`, wrap the result: + +```erl +Binary = iolist_to_binary(json:encode(Map)). +``` + +If you are writing to a socket, file, or HTTP response body, iodata works directly and the conversion is unnecessary. + +### Encoding differences + +`json:encode/1` does not accept the atom `undefined`. It only handles `true`, `false`, and `null` as atom values. If your maps may contain `undefined` values, strip them before encoding: + +```erl +strip_undefined(Map) when is_map(Map) -> + maps:filtermap( + fun + (_K, undefined) -> false; + (_K, V) when is_map(V) -> {true, strip_undefined(V)}; + (_K, _V) -> true + end, + Map + ). + +json:encode(strip_undefined(MyMap)). +``` + +### Error handling summary + +| Scenario | njson | json (OTP) | +| --- | --- | --- | +| Decode success | `{ok, Term}` | `Term` | +| Decode failure | `{error, Reason}` | Throws exception | +| Encode success | `{ok, Binary}` | `IoData` | +| Encode failure | `{error, Reason}` | Throws exception | + +### Quick reference + +| njson | json (OTP) | Notes | +| --- | --- | --- | +| `{ok, Map} = njson:decode(Bin)` | `Map = json:decode(Bin)` | Throws on invalid input | +| `{ok, Bin} = njson:encode(Map)` | `Bin = iolist_to_binary(json:encode(Map))` | Or use iodata directly | +| `{ok, IoList} = njson:encode(Map, true)` | `IoData = json:encode(Map)` | Already iodata | +| `case njson:decode(Bin) of {error,_} -> ...` | `try json:decode(Bin) catch _:_ -> ...` | Error handling | + ## Support Any doubt or suggestion? Please, check out [our issue tracker](https://github.com/nomasystems/njson/issues).