There is a Play solution here that does not require you to specify default values ββtwice or in some strange place - it uses a macro to find the corresponding default at compile time.
First for the case class:
case class User(id: Int = 0, name: String = "John Doe", gender: String = "M")
Then you need to define DefaultFinder , as I described in this blog post . Then you practically did:
import DefaultFinder._ import play.api.libs.json._ import play.api.libs.functional.syntax._ implicit val userReads: Reads[User] = ( (__ \ 'id).readNullable[Int] and (__ \ 'name).readNullable[String] and (__ \ 'gender).readNullable[String] )((id, name, gender) => new User( id = if (id.isEmpty) default else id.get, name = if (name.isEmpty) default else name.get, gender = if (gender.isEmpty) default else gender.get ))
And finally:
scala> Json.fromJson[User](Json.parse("""{ "id": 1, "name": "Foo McBar" }""")) res0: play.api.libs.json.JsResult[User] = JsSuccess(User(1,Foo McBar,M),) scala> Json.fromJson[User](Json.parse("""{ "id": 2, "gender": "X" }""")) res1: play.api.libs.json.JsResult[User] = JsSuccess(User(2,John Doe,X),)
Note that I do not use getOrElse because the macro does not support it, but it can easily be made more general - it was just a brief proof of concept.
Travis brown
source share