What is a good way to handle default values with spray-json
Asked Answered
B

3

6

In some cases default values make more sense than optionals in case classes:

case class Car(numberOfWheels:Int = 4, color:String)

case class Car(numbeOfWheels:Option[Int], color:String) //silly

In the first case I'd expect to be able to easily convert the following json to an instance:

{"color":"red"}

But with a standard jsonFormat2(Car), spray-json complains about missing value for numberOfWheels.

How do I work around this most cleanly?

Buatti answered 1/4, 2013 at 9:32 Comment(0)
F
8

I stumbled upon the same problem. I've create a patch that solves it for me. It makes fields with a default value optional.

https://github.com/spray/spray-json/pull/56

update: PR is updated and still open https://github.com/spray/spray-json/pull/93

Fontaine answered 19/5, 2013 at 12:11 Comment(2)
it's been a while, the PR has been updated: github.com/spray/spray-json/pull/93 . Hopefully we wont have to wait for another 2 years.Perlis
Another 2 years passed. Still not merged :(Vadavaden
G
3

I have never used spray, but here's my guess about what may work:

case class Car(numberOfWheels: Int, color: String) {
  def this(color: String) = this(4, color)
}

object Car {
  def apply(color: String) = new Car(color)
}

Maybe now jsonFormat1(Car) will work.

Gleesome answered 1/4, 2013 at 18:8 Comment(2)
Thanks for the suggestion, but, it's not quite that simple unfortunately.Buatti
This would work if you point spray-json to the proper apply function by doing jsonFormat1(Car.apply)Buatti
A
1

The fix I found for the same issue was to implement my own jsonFormat:

implicit object carFormat extends JsonFormat[Car] {
  def write(car: Car): JsObject = {
    val fields = List(
      ("numberOfWheels" -> JsNumber(car.numberOfWheels)),
      ("color" -> JsString(car.color))
    )
    JsObject(fields: _*)
  }

  def read(json: JsValue): Car = {
    val numberOfWheels = fromField[Option[Int]](json, "numberOfWheels")
    val color = fromField[String](json, "color")
    Car(numberOfWheels.getOrElse(4), color)
  }
}
Accompaniment answered 16/10, 2019 at 14:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.