As the name implies, jackson-js
is heavily inspired by the famous Java FasterXML/jackson library.
It can be used on both client (browser) and server (Node.js) side.
Why this library? What's the difference between using this library instead of JSON.parse
and JSON.stringify
?
For simple cases, you don't need this library of course, you can just use JSON.parse
and JSON.stringify
to serialize/deserialize JSON.
With jackson-js
, you can easily manipulate your JavaScript objects/values serialization/deserialization using decorators such as @JsonProperty()
, @JsonFormat()
, @JsonIgnore()
, and more. However, this library uses JSON.parse
and JSON.stringify
under the hood.
Furthermore:
- it not only deserialize JSON text into a JavaScript object, it also converts it into an instance of the class specified in the
context
option (similar packages are: class-transformer and TypedJSON); instead, withJSON.parse
you will get just a simple plain (literal) JavaScript object (justObject
type); - it supports more advanced Object concepts such as polymorphism and Object identity;
- it supports cyclic object serialization/deserialization;
- it supports serialization/deserialization of other native JavaScript types:
Map
,Set
,BigInt
, Typed Arrays (such asInt8Array
);
This library can be useful in more complex cases, for example when you want to:
- manipulate JSON in depth;
- restore a JavaScript type (a similar package is class-transformer);
- preserve type information (using polymorphic type handling decorators:
@JsonTypeInfo
,@JsonSubTypes
, and@JsonTypeName
. A similar package is TypedJSON); - hide some properties for certain HTTP endpoints or some other external service;
- have different JSON response for some external application or manage different JSON data coming from other application (for example you need to communicate with a Spring Boot application that uses different JSON Schema for the same model or with other applications made with Python, PHP, etc...);
- manage cyclic references;
- manage other JavaScript native types such as Maps and Sets;
- etc.
Most of the use cases of the Java FasterXML/jackson annotations are similar or equal.
npm install --save jackson-js
API docs can be found here.
The main classes that jackson-js
offers to serialize and deserialize JavaScript objects are: ObjectMapper
, JsonStringifier
and JsonParser
.
ObjectMapper
provides functionality for both reading and writing JSON and applies jackson-js
decorators. It will use instances of JsonParser
and JsonStringifier
for implementing actual reading/writing of JSON. It has two methods:
stringify(obj: T, context?: JsonStringifierContext): string
: a method for serializing a JavaScript object or a value to a JSON string with decorators applied;parse(text: string, context?: JsonParserContext): T
: a method for deserializing a JSON string into a JavaScript object/value (of typeT
, based on the context given) with decorators applied.
JsonParser
provides functionality for writing JSON and applies jackson-js
decorators. The main methods are:
parse(text: string, context?: JsonParserContext): T
: a method for deserializing a JSON string into a JavaScript object/value (of typeT
, based on the context given) with decorators applied;transform(value: any, context?: JsonParserContext): any
: a method for applyingjackson-js
decorators to a JavaScript object/value parsed. It returns a JavaScript object/value with decorators applied.
JsonStringifier
provides functionality for reading JSON and applies jackson-js
decorators. The main methods are:
stringify(obj: T, context?: JsonStringifierContext): string
: a method for serializing a JavaScript object or a value to a JSON string with decorators applied;transform(value: any, context?: JsonStringifierContext): any
: a method for applyingjackson-js
decorators to a JavaScript object/value. It returns a JavaScript object/value with decorators applied and ready to be JSON serialized.
Decorators available:
- JsonAlias (decorator options: JsonAliasOptions)
- JsonAnyGetter (decorator options: JsonAnyGetterOptions)
- JsonAnySetter (decorator options: JsonAnySetterOptions)
- JsonAppend (decorator options: JsonAppendOptions)
- JsonBackReference (decorator options: JsonBackReferenceOptions)
- JsonClassType (decorator options: JsonClassTypeOptions)
- JsonCreator (decorator options: JsonCreatorOptions)
- JsonDeserialize (decorator options: JsonDeserializeOptions)
- JsonFilter (decorator options: JsonFilterOptions)
- JsonFormat (decorator options: JsonFormatOptions)
- JsonGetter (decorator options: JsonGetterOptions)
- JsonIdentityInfo (decorator options: JsonIdentityInfoOptions)
- JsonIdentityReference (decorator options: JsonIdentityReferenceOptions)
- JsonIgnore (decorator options: JsonIgnoreOptions)
- JsonIgnoreProperties (decorator options: JsonIgnorePropertiesOptions)
- JsonIgnoreType (decorator options: JsonIgnoreTypeOptions)
- JsonInclude (decorator options: JsonIncludeOptions)
- JsonInject (decorator options: JsonInjectOptions)
- JsonManagedReference (decorator options: JsonManagedReferenceOptions)
- JsonNaming (decorator options: JsonNamingOptions)
- JsonProperty (decorator options: JsonPropertyOptions)
- JsonPropertyOrder (decorator options: JsonPropertyOrderOptions)
- JsonRawValue (decorator options: JsonRawValueOptions)
- JsonRootName (decorator options: JsonRootNameOptions)
- JsonSerialize (decorator options: JsonSerializeOptions)
- JsonSetter (decorator options: JsonSetterOptions)
- JsonSubTypes (decorator options: JsonSubTypesOptions)
- JsonTypeId (decorator options: JsonTypeIdOptions)
- JsonTypeIdResolver (decorator options: JsonTypeIdResolverOptions)
- JsonTypeInfo (decorator options: JsonTypeInfoOptions)
- JsonTypeName (decorator options: JsonTypeNameOptions)
- JsonUnwrapped (decorator options: JsonUnwrappedOptions)
- JsonValue (decorator options: JsonValueOptions)
- JsonView (decorator options: JsonViewOptions)
The most important decorators are:
@JsonProperty()
: each class property (or its getter/setter) must be decorated with this decorator, otherwise deserialization and serialization will not work properly! That's because, for example, given a JavaScript class, there isn't any way or API (such as Reflection API for Java) to get for sure all the class properties; also because, sometimes, compilers such as TypeScript and Babel, can strip class properties after compilation from the class properties declaration;@JsonClassType()
: this decorator, instead, is used to define the type of a class property or method parameter. This information is used during serialization and, more important, during deserialization to know about the type of a property/parameter. This is necessary because JavaScript isn't a strongly-typed programming language, so, for example, during deserialization, without the usage of this decorator, there isn't any way to know the specific type of a class property, such as aDate
or a custom Class type.
Here is a quick example about this two decorators:
class Book {
@JsonProperty() @JsonClassType({type: () => [String]})
name: string;
@JsonProperty() @JsonClassType({type: () => [String]})
category: string;
}
class Writer {
@JsonProperty() @JsonClassType({type: () => [Number]})
id: number;
@JsonProperty() @JsonClassType({type: () => [String]})
name: string;
@JsonProperty() @JsonClassType({type: () => [Array, [Book]]})
books: Book[] = [];
}
- Jackson-js: Powerful JavaScript decorators to serialize/deserialize objects into JSON and vice versa (Part 1) - Article available at [itnext.io | dev.to].
- Jackson-js: Examples for client (Angular) and server (Node.js) side (Part 2) - Article available at [medium.com | dev.to]
Code examples can be found inside the tests
folder and in this example repository. The example repository gives 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.