zio-json

zio-json

  • Overview
  • Interop modules
  • API
  • About

›Overview

Overview

  • Summary
  • Decoding
  • Encoding

Encoding

Automatic Derivation

Assume we want to encode this case class

case class Banana(curvature: Double)

To produce JSON from our data we define a JsonEncoder like this:

import zio.json._

object Banana {
  implicit val encoder: JsonEncoder[Banana] =
    DeriveJsonEncoder.gen[Banana]
}
Banana(0.5).toJson
// res0: String = "{\"curvature\":0.5}"

ADTs

Say we extend our data model to include more data types

sealed trait Fruit

case class Banana(curvature: Double) extends Fruit
case class Apple (poison: Boolean)   extends Fruit

we can generate the encoder for the entire sealed family

import zio.json._

object Fruit {
  implicit val encoder: JsonEncoder[Fruit] =
    DeriveJsonEncoder.gen[Fruit]
}
val apple: Fruit = Apple(poison = false)
// apple: Fruit = Apple(poison = false)
apple.toJson
// res2: String = "{\"Apple\":{\"poison\":false}}"

Almost all of the standard library data types are supported as fields on the case class, and it is easy to add support if one is missing.

Manual instances

Sometimes it is easier to reuse an existing JsonEncoder rather than generate a new one. This can be accomplished using convenience methods on the JsonEncoder typeclass to derive new decoders:

trait JsonEncoder[A] {
  def contramap[B](f: B => A): JsonEncoder[B]
  ...
}

.contramap

We can use contramap from an already existing encoder:

import zio.json._

case class FruitCount(value: Int)

object FruitCount {
  implicit val encoder: JsonEncoder[FruitCount] =
    JsonEncoder[Int].contramap(_.value)
}

FruitCount(3).toJson
// res3: String = "3"
← Decoding
  • Automatic Derivation
    • ADTs
  • Manual instances
    • .contramap
zio-json
GitHub
Star
Chat with us on Discord
discord
Additional resources
Scaladoc of zio-json
Copyright © 2022 ZIO Maintainers