DEV Community

Lorenzo Pichilli
Lorenzo Pichilli

Posted on • Originally published at Medium

Jackson-js: Examples for client (Angular) and server (Node.js) side (Part 2)

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)”.

In this article, I will give a simple example using the jackson-js library with Angular 9 for the client side and two examples for the server side: one using Node.js + Express + SQLite3 (with Sequelize 5) and another one using Node.js + LoopBack 4.

Full code examples can be found in this repository.

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:


Book model:

Services

Services that will be used to get/push data from/to the server side.
Writer Service:


Book Service:

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.

Server side: Node.js + Express + SQLite3 (with Sequelize 5)

For this case, we will implement a simple Node.js Express application using an in-memory SQLite 3 database (with Sequelize 5), 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:


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:


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 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:

Book model:

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.

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

The parsed response of the client side after calling “/writers/public” endpoint of the Node.js + LoopBack 4 server.

Alt Text

The parsed response of the client side after calling “/books” endpoint of the Node.js + Express + SQLite3 (with Sequelize 5) server.

Top comments (0)