Jackson-js: Examples for client (Angular) and server (Node.js) side (Part 2)
Tags: decorators, javascript, jsonparse, jsonstringify
Published: 2020-05-13 16:03:08

---
title: Jackson-js: Examples for client (Angular) and server (Node.js) side (Part 2)
published: true
description: jackson-js is heavily inspired by the famous Java FasterXML/jackson library. It offers powerful JavaScript decorators to write and read JSON.
tags: decorators, javascript, json-parse, json-stringify
cover_image:
canonical_url: https://medium.com/@pichillilorenzo/jackson-js-examples-for-client-and-server-side-part-2-7e66df74c851
---
*This is the second part of a two-part series. You should read the first part “[Jackson-js: Powerful JavaScript decorators to serialize/deserialize objects into JSON and vice versa (Part 1)](https://dev.to/pichillilorenzo/jackson-js-powerful-javascript-decorators-to-serialize-deserialize-objects-into-json-and-vice-versa-part-1-5484)”.*

In this article, I will give a simple example using the [`jackson-js`](https://github.com/pichillilorenzo/jackson-js) library with Angular 9 for the client side and two examples for the server side: one using Node.js + [Express](http://expressjs.com/) + SQLite3 (with [Sequelize 5](https://sequelize.org/)) and another one using Node.js + [LoopBack 4](https://github.com/strongloop/loopback-next).

Full code examples can be found in [this repository](https://github.com/pichillilorenzo/jackson-js-examples).

## Client side: Angular 9
For the client side, we will create a very basic Angular 9 application consisting of 2 models (`Writer` and `Book`), 2 services to communicate with the server side, and a home component that will call these 2 services.

### Models
**Writer model**:
{% gist https://gist.github.com/pichillilorenzo/f6b64d2a0b4338788515181dbf56092e %}
**Book model**:
{% gist https://gist.github.com/pichillilorenzo/59244090ce1338d0fe99a02b6182cddd %}

### Services
Services that will be used to get/push data from/to the server side.
**Writer Service**:
{% gist https://gist.github.com/pichillilorenzo/a9365937ab5be4a711eed8de315c6f94 %}
**Book Service**:
{% gist https://gist.github.com/pichillilorenzo/7b4c01e58a6143454b715cf71b290235 %}

### Home Component
A very basic component that will be used to call each method of each service and to print the responses data to the browser console.
{% gist https://gist.github.com/pichillilorenzo/3673113d8cc2b390476584fc42b34b03 %}

## Server side: Node.js + Express + SQLite3 (with Sequelize 5)
For this case, we will implement a simple Node.js [Express](http://expressjs.com/) application using an in-memory SQLite 3 database (with [Sequelize 5](https://sequelize.org/)), consisting of 2 entities (Writer and Book). This Express application will offer endpoints used by the client side to get/add data from/to the database. Also, it will have 2 Jackson Views has an example: `ProfileViews.public` and `ProfileViews.registered`.

### Models
Because each class model extends the Sequelize.Model class, we need to ignore its enumerable properties using the `@JsonIgnoreProperties` decorator, otherwise, serialization won't work properly.

**Writer model**:
{% gist https://gist.github.com/pichillilorenzo/e9d6cacaa0c52edfd1671b175f65f0dd %}
As we can see, the writer model has a static creator method named buildFromJson decorated with the `@JsonCreator` decorator. This method will be used during deserialization in order to create an instance of the Writer class model using Sequelize 5 API.

Also, I defined a getter method for the books property using `@JsonGetter` in order to get the associated data (one-to-many relationship with `Book`) through the Sequelize `get()` method. Without this, during serialization, the `books` property will be empty. Another way is to call the Sequelize `get()` or `toJSON()` method for each model that needs to be serialized before serialization. This is needed because Sequelize wraps all it’s return values in a virtual object that contains metadata, so we unwrap them.

**Book model**:
{% gist https://gist.github.com/pichillilorenzo/4c37f5d12ca926843cf15b02e52230c5 %}
Same as `Writer`, we have a static creator method used to build the Book instance and a getter method for the writer property. Also, in the `@JsonIgnoreProperties` decorator, I added the `writerId` property (that is automatically added by Sequelize) in order to exclude it from the generated JSON content.

## Server side: Node.js + LoopBack 4
Instead, for this case, we will implement a simple [LoopBack 4](https://github.com/strongloop/loopback-next) application using a file data source as the database. This application will offer endpoints used by the client side to get/add data from/to the database. Also here, it will have 2 Jackson Views has an example: `ProfileViews.public` and `ProfileViews.registered`.

### Models
LoopBack 4 Entity class doesn't wrap our entities, so we don't need to use `@JsonIgnoreProperties` decorator like on Sequelize.

**Writer model**:
{% gist https://gist.github.com/pichillilorenzo/b5139524b93022b3fdfe47a3afc89e26 %}

**Book model**:
{% gist https://gist.github.com/pichillilorenzo/d8bb040bf0831d655c4801f62d848cb3 %}

### LoopBack Custom “object-mapper” Interceptor
LoopBack gives us the ability to create custom interceptors. In this case, I created a global interceptor called `object-mapper` that will be used by the controllers to read and write JSON content using the `jackson-js` library.
{% gist https://gist.github.com/pichillilorenzo/b19b54e8f6808529dc8cdd8d124bf18c %}

## Jackson Context Groups
For both server side examples, I defined 2 context groups: `writerContextApi` and `bookContextApi`. They are used to enable/disable specific decorators based on which API endpoint the client is calling.
- `writerContextApi`: it is used when the client is calling `/writers/*` endpoints to enable the `@JsonManagedReference` decorator and disable the `@JsonIgnoreProperties` decorator on the `Writer.books` property and to enable the `@JsonBackReference` decorator on the `Book.writer` property;
- `bookContextApi`: it is used when the client is calling `/books/*` endpoints to enable the `@JsonIgnoreProperties` decorator on the `Writer.books` property.

## RESTful API Endpoints available
Both servers run at `http://localhost:8000` and, for each one, I created a function named `initDB` that will initialize the database with fake data at server startup.

Endpoints are:
- `/writers/public`: get (“GET”) all writers (with books) using `ProfileViews.public` Jackson view;
- `/writers`: get (“GET”) all writers (with books) or add (“POST”) a new writer;
- `/books/public`: get (“GET”) all books (each one with its writer) using `ProfileViews.public` Jackson view;
- `/books`: get (“GET”) all books (each one with its writer) or add (“POST”) a new book.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/bo3fwig817eazik5c2li.png)
<figcaption>The parsed response of the client side after calling “/writers/public” endpoint of the Node.js + LoopBack 4 server.</figcaption>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/donxiehbh0ijsl65xxrx.png)
<figcaption>The parsed response of the client side after calling “/books” endpoint of the Node.js + Express + SQLite3 (with Sequelize 5) server.</figcaption>