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 theWriter.books
property and to enable the@JsonBackReference
decorator on theBook.writer
property; -
bookContextApi
: it is used when the client is calling/books/*
endpoints to enable the@JsonIgnoreProperties
decorator on theWriter.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) usingProfileViews.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) usingProfileViews.public
Jackson view; -
/books
: get (“GET”) all books (each one with its writer) or add (“POST”) a new book.
Top comments (0)