Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play JSON Reads/Writes with single-parameter case classes

This creates a Writes for a case class

import play.api.libs.json._
import play.api.libs.functional.syntax._

case class A(a: String, b: String, c: String)
(JsPath.write[String] and
    JsPath.write[String] and
    JsPath.write[String])(unlift(A.unapply))

This can be extended to work for 2, 3, 4, 5, 6, etc. parameters...but not 1.

case class B(a: String)
(JsPath.write[String])(unlift(B.unapply))

Compiler error:

error: overloaded method value write with alternatives:
  (t: String)(implicit w:  play.api.libs.json.Writes[String])play.api.libs.json.OWrites[play.api.libs.json.JsValue] <and>
  (implicit w: play.api.libs.json.Writes[String])play.api.libs.json.OWrites[String]
  cannot be applied to (B => String)
              (JsPath.write[String])(unlift(B.unapply))
                           ^

A similar problem happens for Reads.

How can I get Reads and Writes for single-parameter case clases?

like image 816
Paul Draper Avatar asked Dec 15 '14 04:12

Paul Draper


People also ask

What is reads and writes type in play JSON?

Play JSON provides the Reads and Writes typeclasses to define how to read or write specific types. You can get these either by using Play's automatic JSON macros, or by manually defining them. You can also read JSON from a JsValue using validate, as and asOpt methods.

What is the use of play JSON?

Play JSON provides a convenient functional DSL for constructing Reads and Writes. For example, assume I have the following classes: It is also possible to implement custom logic by implementing the Reads, Writes and/or Format traits manually, but we recommend using the automatic conversion macros or the functional DSL if possible.

How do I implement custom logic in play JSON?

For example, assume I have the following classes: It is also possible to implement custom logic by implementing the Reads, Writes and/or Format traits manually, but we recommend using the automatic conversion macros or the functional DSL if possible. Play JSON is licensed under the Apache license, version 2.

What are jsstring and jsboolean in JSON?

JsString: a JSON string. JsBoolean: a JSON boolean, either JsTrue or JsFalse. JsNull: the JSON null value. The play.api.libs.json package includes several features for constructing JSON from scratch, as well as for converting to and from case classes. The play.api.libs.json.Json object has several methods for reading and writing:


1 Answers

Like Travis said:

  1. Transforming an existing Reads: use the map method
  2. Transforming an existing Writes: use contramap

However, contramap only works on Writes that produce JsObject. Your writes will fail at runtime:

val w = JsPath.write[String].contramap[B](_.a)
scala> w.writes(B("Hello"))
java.lang.RuntimeException: when empty JsPath, expecting JsObject

You can create a Writes "from scratch" using Writes.apply:

Writes[B](b => JsString(b.a))

Similarly you can create a Reads using Reads.apply.

like image 96
Dimitri Avatar answered Oct 07 '22 00:10

Dimitri