Introduction to zio-json | Encoding Decoding

Reading Time: 2 minutes
Zio Json

In this blog we discuss how encoding and decoding of data is perform in zio using the zio-json.

According to ZIO documentation, we know ZIO is a library for asynchronous and concurrent programming that promotes pure functional programming.

At the core of ZIO is ZIO, a powerful effect type inspired by Haskell’s IO monad.The ZIO[R, E, A] data type has three type parameters:

  • R – Environment Type:- The effect requires an environment of type R.
  • E – Failure Type :- The effect may fail with a value of type E.
  • A – Success Type:- The effect may succeed with a value of type A.

As we perform different operations using this effectfull monad ZIO, we encounter to deal with encoding a type data to JSON and to decode JSON data into particular type.

For this pupose we use zio-json to encode and decode JSON in a effectful way.

Zio Json

This is the JSON library intergrate with ZIO to provide support for encoding and decoding JSON.

For use of zio-json we have to add following dependency in our build.sbt.

libraryDependencies += "dev.zio" %% "zio-json" % "0.1.5"

Zio JSON requires JsonEncoder and JsonDecoder implicit values in scope for each type you want to serialize.

implicit val decoder: JsonDecoder[T] =

    DeriveJsonDecoder.gen[A]

  implicit val encoder: JsonEncoder[T] =

    DeriveJsonEncoder.gen[A]

According to official documentation a JsonDecoder[A] instance has the ability to decode JSON to values of type A on the other hand JsonEncoder[A] instance has the ability to encode values of type A to JSON.

Let’s start with some basic examples of zio-json.

Example 1

implicit val employeeDecoder: JsonDecoder[Employee] = 

DeriveJsonDecoder.gen[Employee]


case class Employee(id: Int,name: String)


	val jsonData =

		"""
			|{

			|"id": 1,

			|"name": "John"

			|}

			|""".stripMargin

	val decodeData = jsonData.fromJson[Employee]

//Output:- Right(Employee(1,John))

Firstly we define a case class Employee and decoder instance for coverting JSON data to Employee type. After this we also create the JSON data which is to be decode.

Using the fromJson method which decode the raw JSON string as an Employee type.

This method also requires the implict JsonDecoder of type Employee as it returns the output in Either form. If any error occured it gives the result in Left.

Example 2

implicit val employeeEncoder: JsonEncoder[Employee] = 

DeriveJsonEncoder.gen[Employee]

	val data = Employee(1,"John")


	val encodeData = data.toJson


//Output- {"id":1,"name":"John"}

Secondly we encode the data of type Employee to JSON by using toJson method which require a implicit JsonEncoder of type Employee and we gets the output in JSON form.

We can also use a proper handling of this conversion in a effectful way using the ZIO monad. Lets use this mechanism for encode and decode JSON data.

val decodedData = 

ZIO.fromEither(jsonData.fromJson[Employee].left.map(errorMessage => new 

RuntimeException(errorMessage)))

val encodedData = ZIO.effect(data.toJson)

In above code we handle proper exception handling of the conversion as sometimes there some error occur in the conversion process.

In conclusion zio json provide a proper structure of the serialize and deserialize JSON data using the ZIO monad in a effectfull way.

Above all we majorly focuses on functional programming so these conversion should be done smoothly with high performance,fast compilation and in a secure way. Zio Josn is provide all these feature in porper way.

References

zio.dev

zio-json

Written by 

Akash Kumar is a Software Consultant at Knoldus Software LLP. He has done B.tech from Abdul Kalam Technical University. He is majorly focused on Scala and Angular. On the personnel side, he loves to play Cricket and online video games.