I have an actor which receives JsValue from a websocket in play 2.3. I also have a case class that defines a Reads converter. When I try to pattern match against the case class it always matches against JsValue instead of the case class.
case class Ack(messageType: String, messageId: Int){
implicit val ackReads: Reads[Ack] = (
(JsPath \ "message_type").read[String] and
(JsPath \ "message_id").read[Int]
)(Ack.apply _)
}
class ChannelActor(out: ActorRef) extends Actor{
def receive = {
case a: Ack =>
println(s"Acknowledged! $a")
case msg: JsValue =>
println("Got other jsvalue")
case _ =>
println("Got something else")
}
}
How can I pattern match the JsValue I am receiving from the websocket against the Reads validator in the case class?
Edit: I have found a way to work around this by manually pattern matching against the JsValue to figure out what type I then need to validate. The code looks like this now:
case class Ack(messageType: String, messageId: Int)
object Ack{
implicit val ackReads: Reads[Ack] = (
(JsPath \ "message_type").read[String](verifying[String](_ == "ack")) and
(JsPath \ "message_id").read[Int]
)(Ack.apply _)
implicit val ackWrites: Writes[Ack] = (
(JsPath \ "message_type").write[String] and
(JsPath \ "message_id").write[Int]
)(unlift(Ack.unapply))
}
class ChannelActor(out: ActorRef) extends Actor{
def receive = {
case msg: JsValue =>
(msg \ "message_type").asOpt[String] match {
case Some("ack") =>
msg.validate[Ack] match{
case ack: JsSuccess[Ack] => println("got valid ack message")
case e: JsError => out ! Json.obj("error" -> s"invalid format for ack message ${JsError.toFlatJson(e).toString()}")
}
case None => out ! Json.obj("error" -> "you must send a message_type with your json object")
case t => out ! Json.obj("error" -> s"unknown message type ${t.get}")
}
case _ => out ! Json.obj("error" -> "unknown message format")
}
}
This achieves what I want but I have the feeling that it is not the "correct" or most elegant solution to validating JSON messages in Play and will be messy as I implement more message types.