Json encode/decode in Js_of_ocaml

Hi,

What would be the recommended way to encode/decode json in Js_of_ocaml? Could you please show me some code example? Thanks.

If you want to use the browser’s built-in encode/decode, I think the best/easiest way to do so would be to use @dbuenzli’s brr, specifically the JSON module.

Disclaimer: I haven’t used it myself, but the API looks pretty simple, and it should behave pretty similarly to the Base64 example here.

1 Like

You can use what @zbaylin mentions but note that this API will simply return/take for now a JavaScript object, it uses your browser’s JSON.{parse,stringify} functions.

So if you are looking to codec OCaml values you will have to further query the object with the Jv module which is quite low level (e.g. see the to,of_json functions in the model of the todomvc example, note that the functions there do not handle errors).

In the future I’d like to provide a few combinators to easily interoperate with OCaml values, that’s the reason for the warning about the fact that this interface will likely change in the future.

2 Likes

I had the same need and created my own library for that. It use the browser built-in encode/decode, but it is presented through a type-safe API (use it if if you control the data you are reading).

1 Like

To encode/decode JSON into custom types, as far as I know the best solutions are ppx_yojson_conv or ppx_deriving_yojson. Lots of examples and usage in the readme file, GitHub - janestreet/ppx_yojson_conv: [@@deriving] plugin to generate Yojson conversion functions

2 Likes

It’s rather to encode/decode your types into custom JSON. Also of course that’s not so great for your page JavaScript size budget.

Neither is JSOO :wink:

On a more serious note, doesn’t JSOO have some way to do whole-program optimization?

It can get you a long way if you don’t follow misguided advices :wink:

4 Likes

You can use json-data-encoding which comes with a browser backend for JSOO. For a type such as

type t = { foo: float list ; bar: string }

you can define en encoding

let e =
   let open Json_data_encoding.Json_encoding in
   conv
      (fun {foo; bar} -> (foo, bar))
      (fun (foo, bar) -> {foo; bar})
      (obj2
         (req "foo" (list float))
         (req "bar" string))

and then you can use this encoding to parse some JSON or stringify your values.

1 Like

One thing to note if you use yojson in the browser: it’s decoder for lists is a recursive call which jsoo is not able to transform into a form that does not cause a stack overflow, so if you are using it to decode large lists you’ll have to define your of_yojson yourself.

3 Likes

The library Fmlib_js has modules to decode and encode javascript objects via Js_of_ocaml. You can find the decoder at https://hbr.github.io/fmlib/odoc/fmlib_js/Fmlib_js/Base/Decode/index.html and the encoder at https://hbr.github.io/fmlib/odoc/fmlib_js/Fmlib_js/Base/Value/index.html.

The library decodes javascript values directly into ocaml objects without using any intermediate syntax tree.

You can find the complete documentation for Fmlib_js at https://hbr.github.io/fmlib/odoc/fmlib_js/index.html.

Regards
Helmut

2 Likes

There is this ppx which seems to be perfect for the job: GitHub - little-arhat/ppx_jsobject_conv: ppx rewriter for [@@deriving jsobject]

  • Shouldn’t increase bundle size too much, compared to manual encoders/decoders implementation
  • Fast, as it is designed to be used in combination with browsers-implemented JSON.parse.

Some examples in the library tests.

1 Like