Module Js.Json

Provide utilities for json

Efficient JSON encoding using JavaScript API

Types

type t;

The JSON data structure

type kind(_) =
  1. | String : kind(string)
  2. | Number : kind(float)
  3. | Object : kind(Js__.Js_dict.t(t))
  4. | Array : kind(array(t))
  5. | Boolean : kind(bool)
  6. | Null : kind(Js__.Js_types.null_val)
;

Underlying type of a JSON value

type tagged_t =
  1. | JSONFalse
  2. | JSONTrue
  3. | JSONNull
  4. | JSONString(string)
  5. | JSONNumber(float)
  6. | JSONArray(array(t))
;

Accessor

let classify: t => tagged_t;
let test: 'a => kind('b) => bool;

test v kind returns true if v is of kind

let decodeString: t => option(string);

decodeString json returns Some s if json is a string, None otherwise

let decodeNumber: t => option(float);

decodeNumber json returns Some n if json is a number, None otherwise

let decodeObject: t => option(Js__.Js_dict.t(t));

decodeObject json returns Some o if json is an object, None otherwise

let decodeArray: t => option(array(t));

decodeArray json returns Some a if json is an array, None otherwise

let decodeBoolean: t => option(bool);

decodeBoolean json returns Some b if json is a boolean, None otherwise

let decodeNull: t => option(Js__.Js_internal.null('a));

decodeNull json returns Some null if json is a null, None otherwise

Construtors

Those functions allows the construction of an arbitrary complex JSON values.

let null: t;

null is the singleton null JSON value

let string: string => t;

string s makes a JSON string of the string s

let number: float => t;

number n makes a JSON number of the float n

let boolean: bool => t;

boolean b makes a JSON boolean of the bool b

let object_: Js__.Js_dict.t(t) => t;

object_ dict makes a JSON object of the Js.Dict.t dict

let array: array(t) => t;

array a makes a JSON array of the Js.Json.t array a

The functions below are specialized for specific array type which happened to be already JSON object in the Melange runtime. Therefore they are more efficient (constant time rather than linear conversion).

let stringArray: array(string) => t;

stringArray a makes a JSON array of the string array a

let numberArray: array(float) => t;

numberArray a makes a JSON array of the float array a

let booleanArray: array(bool) => t;

booleanArray makes a JSON array of the bool array a

let objectArray: array(Js__.Js_dict.t(t)) => t;

objectArray a makes a JSON array of the JsDict.t array a

String conversion

let parseExn: string => t;

parseExn s parses the string s into a JSON data structure

Returns a JSON data structure

  • raises SyntaxError

    if given string is not a valid JSON. Note SyntaxError is a JavaScript exception.

    (* parse a simple JSON string *)
    
    let json =
      try
        Js.Json.parseExn {| "foo" |}
      with
      | _ -> failwith "Error parsing JSON string"
    in
    match Js.Json.classify json with
    | Js.Json.JSONString value -> Js.log value
    | _ -> failwith "Expected a string"
    (* parse a complex JSON string *)
    
    let getIds s =
      let json =
        try
          Js.Json.parseExn s
        with
        | _ -> failwith "Error parsing JSON string"
      in
      match Js.Json.classify json with
      | Js.Json.JSONObject value ->
        (* In this branch, compiler infer value : Js.Json.t Js.Dict.t *)
        begin match Js.Dict.get value "ids" with
        | Some ids ->
          begin match Js.Json.classify ids with
          | Js.Json.JSONArray ids ->
            (* In this branch compiler infer ids : Js.Json.t array *)
            ids
          | _ -> failwith "Expected an array"
          end
        | None -> failwith "Expected an `ids` property"
        end
      | _ -> failwith "Expected an object"
    
      (* prints `1, 2, 3` *)
      let _ =
        Js.log (getIds {| { "ids" : [1, 2, 3] } |})
let stringify: t => string;

stringify json formats the JSON data structure as a string

Returns the string representation of a given JSON data structure

(* Creates and stringifies a simple JS object *)

let dict = Js.Dict.empty () in
Js.Dict.set dict "name" (Js.Json.string "John Doe");
Js.Dict.set dict "age" (Js.Json.number 30.0);
Js.Dict.set dict "likes"
  (Js.Json.stringArray [|"bucklescript";"ocaml";"js"|]);

Js.log (Js.Json.stringify (Js.Json.object_ dict))
let stringifyWithSpace: t => int => string;

stringify json formats the JSON data structure as a string

Returns the string representation of a given JSON data structure

(* Creates and stringifies a simple JS object with spacing *)

let dict = Js.Dict.empty () in
Js.Dict.set dict "name" (Js.Json.string "John Doe");
Js.Dict.set dict "age" (Js.Json.number 30.0);
Js.Dict.set dict "likes"
  (Js.Json.stringArray [|"bucklescript";"ocaml";"js"|]);

  Js.log (Js.Json.stringifyWithSpace (Js.Json.object_ dict) 2)
let stringifyAny: 'a => option(string);

stringifyAny value formats any value into a JSON string

(* prints ``"foo", "bar"`` *)
Js.log (Js.Json.stringifyAny [| "foo"; "bar" |])

Best-effort serialization, it tries to seralize as many objects as possible and deserialize it back

let deserializeUnsafe: string => 'a;

It is unsafe in two aspects

  • It may throw during parsing
  • when you cast it to a specific type, it may have a type mismatch
let serializeExn: 'a => string;

It will raise in such situations:

  • The object can not be serlialized to a JSON
  • There are cycles
  • Some JS engines can not stringify deeply nested json objects