I'm trying to create a common trait for my Actors to avoid code copypasting, basically like this:
import akka.actor.Actor
import spray.json._
import scala.concurrent.Future
trait ActorResponsive[T] extends Actor {
import DefaultJsonProtocol._
import context.dispatcher
case class Response(success: Boolean,
single: Option[T] = None,
multiple: Option[Seq[T]] = None,
message: Option[String] = None)
implicit val responseFormat = jsonFormat4(Response)
def makeResponse(f: Future[Any]) =
f.map { /*...*/ }.recover { /*...*/ }
.map { case r => r.toJson.compactPrint }
}
Regardless other code flaws, I'm trying to make responseFormat
resolved polymorphically, e.g.:
class PostgresItemActor extends ActorResponsive[Item] {
import com.blahblah.models.ItemJsonProtocol._
override def receive = makeResponse(someFuture)
}
...
class PostgresEventActor extends ActorResponsive[Event] {
import com.blahblah.models.EventJsonProtocol._
override def receive = makeResponse(someFuture)
}
So JsonProtocol for each time responseFormat
is called will be resolved regarding the import in the class, implementing the ActorResponsive
trait. As for now, I'm getting a compile error:
Cannot find JsonWriter or JsonFormat type class for ActorResponsive.this.Response
Probably I'm getting some concept of OOP wrong here, but is it possible to resolve jsonFormat(Response)
for T
or achieve some behaviour like this?
It looks like you need to provide the JsonWriter
as a parameter to your makeResponse
function.
Something along the lines of:
def makeResponse[T: JsonWriter](f: Future[T]) =
f.map { /*...*/ }.recover { /*...*/ }
.map { case r => r.toJson.compactPrint }