reasonml-q-a icon indicating copy to clipboard operation
reasonml-q-a copied to clipboard

How to work with JSON in ReasonML? (parse / stringify)

Open woeps opened this issue 5 years ago • 0 comments

Question

How to convert JSON data to specified types in a program and how do I serialize my data structures into JSON?

Especially for devs coming from js this can be quite confusing.

Given the following example, how would I de-/serialize such types to JSON?

type monthlyCost = [
  | `Euro(float)
  | `UsDollar(float)
];

type subscription = {
  id: string,
  monthlyCost: option(monthlyCost)
};

type user = {
  name: string,
  age: int,
  subscription: option(subscription)
};

Answer

Because ReasonML does not treat JSON as a native data structure like JavaScript, there are typically two steps to working with JSON:

  1. Parsing a string into a JSON data structure
  2. Decoding the JSON data structure into custom types

And the reverse:

  1. Encoding a custom-typed value into JSON
  2. Printing the JSON into a string

This answer assumes that we are talking about ReasonML specifically targeting JavaScript using BuckleScript.

Parsing a string into JSON

Use Js.Json.parseExn. This could throw an exception, so use a try ... with or switch ... expression to handle that as well.

Or use Fetch.Response.json in the bs-fetch bindings for the Fetch API, if you are using Fetch to get JSON from an HTTP response.

There may be other options for getting JSON.

Decoding JSON into custom type

Use decco to auto-derive JSON codecs from type definitions. However note that decco currently does not support polymorphic variants. It does support normal variant types though. And you could hand-write converters for your polymorphic variant types if desired.

Encoding custom data into JSON

Use decco to auto-derive the encoder, with the same caveat as before.

Printing JSON to string

Use Js.Json.stringify.

Further reading

There are other JSON serialization libraries available:

  • bs-json: provides functions to enable writing JSON serializers
  • bs-decode: supports decoding from JSON only, not encoding

woeps avatar Feb 19 '20 12:02 woeps