(Note: this project has been renamed from play-json-variants to play-json-derived-codecs
)
Reads
, OWrites
and OFormat
derivation for algebraic data types (sealed traits and case classes, possibly recursive), powered by shapeless.
Compared to the built-in macros, this project brings support for:
- sealed traits ;
- recursive types ;
- polymorphic types.
The artifacts are built for Scala 2.11, Play 2.5.x and Shapeless 2.3.0.
For Play 2.4.x compatibility see version 3.2
.
import julienrf.json.derived
case class User(name: String, age: Int)
object User {
implicit val reads: Reads[User] = derived.reads
}
The API is simple: the object
julienrf.json.derived
has just three methods.
reads[A]
, derives aReads[A]
;owrites[A]
, derives aOWrites[A]
;oformat[A]
, derives aOFormat[A]
.
By default, sum types (types extending a sealed trait) are represented by a JSON object containing one field whose name is the name of the concrete type and whose value is the JSON object containing the value of the given type.
For instance, consider the following data type:
sealed trait Foo
case class Bar(s: String, i: Int) extends Foo
case object Baz extends Foo
The default JSON representation of Bar("quux", 42)
is the following JSON object:
{
"Bar": {
"s": "quux",
"i": 42
}
}
The default representation of sum types may not fit all use cases. For instance, it is not very practical for enumerations. For this reason, the way sum types are represented is extensible.
For instance, you might want to represent the Bar("quux", 42)
value as the following JSON object:
{
"type": "Bar",
"s": "quux",
"i": 42
}
Here, the type information is flattened with the Bar
members.
You can do so by using the methods in the derived.flat
object:
implicit val fooOWrites: OWrites[Foo] =
derived.flat.owrites((__ \ "type").write[String])
In case you need even more control, you can still implement your own TypeTagOWrites
and TypeTagReads
.
See here.
See here.