# How to generate JSON from a data structure?

**URL:** <https://discuss.ocaml.org/t/how-to-generate-json-from-a-data-structure/1599>\
**Category:** Learning\
**Created:** [February 20, 2018, 10:15pm UTC](https://discuss.ocaml.org/t/how-to-generate-json-from-a-data-structure/1599 "2018-02-20T22:15:37Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![dogweather](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/dogweather/32/847_2.png) [@dogweather](https://discuss.ocaml.org/u/dogweather)\
**Post date:** [February 20, 2018, 10:15pm UTC](https://discuss.ocaml.org/t/how-to-generate-json-from-a-data-structure/1599/1 "2018-02-20T22:15:37Z")

</div>

I’ve been using Haskell to parse HTML and produce well formed JSON. ([Repo](https://github.com/public-law/nevada-revised-statutes-parser)) Is there a way to get this kind of strongly typed, locked-down JSON creation? E.g., in Haskell I define a data type for each kind of thing I want to generate:

```auto
-- The top-level organizational unit in the Nevada Revised Statutes
data Title =
  Title {
    name ∷ Text,
    number ∷ Integer,
    chapters ∷ [Chapter]
}

```

I can then generate the entire JSON tree representing this data type. Does OCaml have any libraries that support something like this? Thanks!

---

<div class="post-metadata">

**Author:** ![bcc32](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/bcc32/32/203_2.png) [@bcc32](https://discuss.ocaml.org/u/bcc32)\
**Post date:** [February 21, 2018, 12:55am UTC](https://discuss.ocaml.org/t/how-to-generate-json-from-a-data-structure/1599/2 "2018-02-21T00:55:20Z")

</div>

I believe using [Yojson](https://github.com/mjambon/yojson) and [ppx\_deriving\_yojson](https://github.com/ocaml-ppx/ppx_deriving_yojson) will do want you want. I’ve never used the latter before, though, so I can’t really speak to how strongly-typed, etc. the serialization/deserialization functions you get are.

---

<div class="post-metadata">

**Author:** ![mjambon](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mjambon/32/6180_2.png) [@mjambon](https://discuss.ocaml.org/u/mjambon)\
**Post date:** [February 21, 2018, 7:20pm UTC](https://discuss.ocaml.org/t/how-to-generate-json-from-a-data-structure/1599/3 "2018-02-21T19:20:26Z")

</div>

Yes, use [atdgen](https://github.com/mjambon/atd). It generates plain `.mli` and `.ml` files which are helpful to see what functions are available and how they are implemented should anything go wrong.

Another aspect of the design is that the ATD file can serve as strict documentation for your API. It is also possible to support code generation for other languages than OCaml. We have the equivalent of atdgen for Java (atdj) and it would be great to have some support for other languages as well.

For your example, you’d write a file `statute.atd` like this:

```auto
type title = {
  name: string;
  number: int;
  chapters: chapter list;
}

type chapter = string

```

Try the following and take look at the files that are generated:

```auto
$ atdgen -t statute.atd
$ atdgen -j -j-std statute.atd
$ atdgen -v statute.atd

```

(t = types, j = json, v = validators and record creators)

Also commonly used are optional fields with or without defaults:

```auto
type preferences = {
  id: string; (* required field *)
  ?img_url: string option; (* defaults to None *)
  ~pets: pet list; (* defaults to the empty list *)
}

```

This allows missing or null json fields. The `_v` generated module provides a function with the following signature:

```auto
val create_preferences : id:string -> ?img_url:string -> ?pets:pet list -> unit -> preferences

```

If you have abstract types, say a user ID that must follow a special syntax, you can use the wrap feature to get an OCaml type that maps to a basic type supported by json, like a string or an int. So instead of having `type id = string`, you can use your special `id` type:

```auto
type id = string wrap <ocaml module="ID">

```

where the `ID` module that you provide contains the following:

```auto
type t (* type of a well-formed ID *)
val wrap : string -> t (* would raise an exception on malformed input *)
val unwrap : t -> string

```

---

<div class="post-metadata">

**Author:** ![Nobody\_Gone](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/nobody_gone/32/1418_2.png) [@Nobody\_Gone](https://discuss.ocaml.org/u/Nobody_Gone)\
**Post date:** [February 22, 2018, 4:05am UTC](https://discuss.ocaml.org/t/how-to-generate-json-from-a-data-structure/1599/4 "2018-02-22T04:05:26Z")

</div>

Depyt is pretty useful too.
