I'm trying to write a simple HTTP client using Scala and spray-client. I'm basing my client on the examples given on Spray docs.
My issue is that the example is creating a new implicit ActorSystem i.e.
implicit val system = ActorSystem()
but I want my client to be reusable and not create a new ActorSystem.
Here's the gist of my code.
trait WebClient {
def get(url: String)(implicit system: ActorSystem): Future[String]
}
object SprayWebClient extends WebClient {
val pipeline: HttpRequest => Future[HttpResponse] = sendReceive
def get(url: String): Future[String] = {
val r = pipeline (Get("http://some.url/"))
r.map(_.entity.asString)
}
}
But I am getting two compiler errors regarding implicits
implicit ActorRefFactory required: if outside of an Actor you need an implicit ActorSystem, inside of an actor this should be the implicit ActorContext WebClient.scala ...
and
not enough arguments for method sendReceive: (implicit refFactory: akka.actor.ActorRefFactory, implicit executionContext: scala.concurrent.ExecutionContext, implicit futureTimeout: akka.util.Timeout)spray.http.HttpRequest => scala.concurrent.Future[spray.http.HttpResponse]. Unspecified value parameters refFactory, executionContext. WebClient.scala...
How should I change the API definitions?
Here's one solution:
and here's another that keeps the original
WebClient.get
signature:The second one is a bit more expensive because the pipeline is created anew every time even if it is theoretically static per
ActorSystem
. I would prefer the first solution and try to find a way to propagate theWebClient
through your application (by using the cake pattern, by passing it around explicitly, or by using other dependency injection techniques).