Json write for DTO with generics


(Alvarotovar) #1

Hello All
Thank you in advance, I need some help, I would like to have a Generic ResponseDTO object, so wrap the rest/json responses, this is my ResponseDTO.scala

package dto

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

case class ResponseDTO[A](codigo : Option[String], resultado : Option[A],
                          mensaje : Option[String]);

This is my Write, is located inside the Controller

implicit val responseDTOWrites : Writes[ResponseDTO[Alarma]] = new Writes[ResponseDTO[Alarma]] {
    def writes(x: ResponseDTO[Alarma]) = {
      Json.obj(
        "codigo" -> x.codigo,
        "resultado" -> x.resultado,
        "mensaje" -> x.mensaje.get
      )
    }
  }

My first service is to return an case class Alarma, this is my Alarma case class

case class Alarma(
                    id : Option[Int],
                    id_alarma :  Option[String],

This is my service method in the Controller

def consultaAla() = Action{
    Ok(new ResponseDTO[Alarma](Some("a"),
      Some(new Alarma(None, None))
      ))
  }

This is my alarma writes

implicit val alarmaWrites: Writes[Alarma] = (
    (JsPath \ "id").write[Option[Int]] and
    (JsPath \ "id_alarma").write[Option[String]] 
    ) (unlift(Alarma.unapply)

Without the generic ResponseDTO case class all works ok, but with it I am getting this error:

 Cannot write an instance of dto.ResponseDTO[
dto.Alarma] to HTTP response. Try to define a Writeable[dto.ResponseDTO[dto.Alarma]]
[error]     Ok(new ResponseDTO[Alarma](Some("a"),
[error]       ^
[error] one error found

Any help will be amazing.


(Nafer Sanabria) #2

@alvarotovar , you’re missing to transform your case class to a JsValue using the Json.toJson[T](T)(implicit writes: Writes[T]) function

Ok(Json.toJson(ResponseDTO[Alarma](Some("a"),
      Some(Alarma(None, None)), None
    )))