BuckleScript JSON Encoding


#1

Hello,

I’ve been using JSON encoding on buckleScript (Reason to be 100% honest) and its a bit verbose. You have to both specify an Encoder and a Decoder which most of the time is 100% identical to the type record you want to serialize.
But today I discovered [@bs deriving abstracrt] which looks amazing and makes a lot of sense. If I understood it correctly, it is capable of inferring a javascript object representation from the type record I have described.
Using the normal Json encoders I created they just create an object that then I have to serialize using Js.Json.stringify. My question is, why not using deriving abstract and then just pipe that tho stringify ? Using a handwritten encoder I am forced to do exactly that so, why not save me the boilerplate ?

I tried this on the REPL, but it is not working because not matching types:

[@bs.deriving abstract]
type person = {
  name: string,
  age: int,
  job: string,
};

Js.log(person(~name="Joe", ~age=20, ~job="teacher")) // This works
Js.log(person(~name="Joe", ~age=20, ~job="teacher") |> Js.Json.stringify ) // This fails

Please tell me that I’m just doing something stupid and that this can work


#2

I don’t entirely understand your question, but one hack to convert your record type to javascript is you can use the identity external to “cast” the abstract type to a Js.Json.t.

eg. (in ocaml syntax):

external personToJs : person -> Js.Json.t = "%identity"

Obviously this is not terribly safe, so if you adopt this approach try to limit its usage or encapsulate it to a scope where you know the type has the [@bs.deriving abstract] annotation.

Example in real life: https://github.com/struktured/bs-holochain/blob/master/src/entry.ml#L50


#3

Oh yes! That is exactly what I was looking for !

Indeed. My plan is to simplify the specific JSON encoding methods of some modules, where I have the entire control over what types are being translated to JSON. Would you say that it is safe to use it that way ? For example, here: https://github.com/danielo515/trainer-reason/blob/master/src/Trainer.re#L34-L41

That is a lot of boilerplate for such a simple structure, and that is just the 50% ! There is also a decoder


#4

This is the kind of situation where I find atdgen to shine. You would define your types in a .atd file and get the converters for free.


#5

That sounds quite interesting too. Could you provide any reference ? Are you talking about this ?https://github.com/mjambon/atd


#6

Yes, this one. Two pages with examples:

Javascript version of the atdgen binary available at https://d.khady.info/atdgen.js.tar if you don’t want to use opam. This part is experimental and not official.


#8

Sounds a bit complicated to setup for a noob, but probably will deserve the effort.
Thank for the article and the links !