Introducing serializr: serializing and deserializing object graphs with ease

Serializing object graphs to JSON and especially deserializing object graphs from JSON is often a cumbersome task in JavaScript. Especially if the object graph doesn’t have a tree shape (e.g. bidirectional references between objects) or uses constructor functions. But even when sticking to plain object trees the data often doesn’t have the desired JSON structure that is needed to integrate with back-end services. Attributes might need to be stripped, or the server API’s change but you don’t want to rewrite your client side code for that.

So that is where “serializr” comes in. A small library that helps decoupling your JSON data representation from your object graphs by providing a simple mechanism to serialize object graphs into JSON and vice versa.

It supports object composition, references, classes, inheritance and other common patterns. Nothing demonstrates that better than a simple example:

This listing introduces three model classes, a Drawing, Box and Arrow. A model as simple as this is already requires manual work to properly serialize it to JSON. Deserialization is even harder. Reconstructing a tree of plain object from JSON is easy, but reconstructing a graph of typed objects usually requires a lot of tedious (de)serialization code if you don’t have an opinionated ORM system in place.

For example a naive “JSON.stringify(drawing)” will emit the boxes twice in the output, one time in the boxes collection, and one time as from/to properties of the arrow:

Data relations: Containment versus association

So let’s alter our data model a bit. The @serializable decorator can be used to indicate that a field should be serialized, and optionally it accepts a strategy (propSchema) that expresses how a field should be serialized. The annotated model looks like this (constructors have been omitted for brevity):

These annotations are created using ESNext / TypeScript decorators. Note that this is optional, at the end of this blog post the ES5 syntax is provided as well.

It is time to meet “serializr.serialize” and “serializr.deserialize”. These functions utilize the above annotations, so serializing into a proper JSON tree and deserializing the JSON into a Drawing again is now as simple as:

The serialize functions picks up the annotations which results in, for example, the “from” property of an arrow being serialized as just the identifier value of a box instead of the complete box. And during deserialization the annotated information is used to construct objects of the proper type. The symbiosis between “identifier” and “reference” makes sure that the relations are restored after deserialization.

Asynchronous deserialization

Customizability

Serializr ain’t the next ORM library

So, if you need something like this, give it a shot. Share your feedback in the github issue tracker or gitter channel. The JSBin with the arrows & boxes example can be found here:

Appendix: Serializr + ES5

Lead Developer @Mendix, JS, TS & React fanatic, dad (twice), creator of MobX, MX RestServices, nscript, mxgit. Created.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store