Below is a simple actor which is required to make a HTTP call to receive data from an API. According to the Akka HTTP Core Request-Level Client-Side API only the ActorSystem
and ActorMaterializer
are needed implicitly.
class MyActor extends Actor {
import context.system
implicit val materializer = ActorMaterializer()
override def receive: Receive = {
case _ => {
val responseFuture: Future[HttpResponse] = Http().singleRequest(HttpRequest(uri = "http://akka.io"))
responseFuture onComplete {
case Success(res) => println(res)
case Failure(t) => println("An error has occured: " + t.getMessage)
}
}
}
}
However, when attempting to compile the application I receive the following error messages:
Error:(18, 48) ambiguous implicit values: both value context in trait Actor of type => akka.actor.ActorContext and method system in trait ActorContext of type => akka.actor.ActorSystem match expected type akka.actor.ActorRefFactory
implicit val materializer = ActorMaterializer()
Error:(18, 48) implicit ActorRefFactory required: if outside of an Actor you need an implicit ActorSystem, inside of an actor this should be the implicit ActorContext
implicit val materializer = ActorMaterializer()
Error:(18, 48) not enough arguments for method apply: (implicit context: akka.actor.ActorRefFactory)akka.stream.ActorMaterializer in object ActorMaterializer. Unspecified value parameter context.
implicit val materializer = ActorMaterializer()
Error:(22, 70) could not find implicit value for parameter fm: akka.stream.Materializer
val responseFuture: Future[HttpResponse] = Http().singleRequest(HttpRequest(uri = "http://akka.io"))
Error:(22, 70) not enough arguments for method singleRequest: (implicit fm: akka.stream.Materializer)scala.concurrent.Future[akka.http.scaladsl.model.HttpResponse]. Unspecified value parameter fm.
val responseFuture: Future[HttpResponse] = Http().singleRequest(HttpRequest(uri = "http://akka.io"))
Error:(23, 22) Cannot find an implicit ExecutionContext. You might pass an (implicit ec: ExecutionContext) parameter to your method or import scala.concurrent.ExecutionContext.Implicits.global.
responseFuture onComplete {
Error:(23, 22) not enough arguments for method onComplete: (implicit executor: scala.concurrent.ExecutionContext)Unit. Unspecified value parameter executor.
responseFuture onComplete {
Is this the correct way to make a HTTP call inside an Akka Actor?
Edit
Included import ExecutionContext.Implicits.global
to fix the last two ExecutionContext
errors.
An implicit ActorRefFactory is required to create the ActorMaterializer. The context property defined in the Actor trait extends ActorRefFactory, and it's implicit. The system property on context, which you imported explicitly, is another implicit candidate for ActorRefFactory, because ActorSystem extends ActorRefFactory.
My suggestion is removing the import and passing it explicitly where it is needed.
class MyActor extends Actor {
// Do not import context.system
// import context.system
implicit val materializer = ActorMaterializer()
override def receive: Receive = {
case _ => {
// use context.system explicitly
val responseFuture: Future[HttpResponse] = Http(context.system)
.singleRequest(HttpRequest(uri = "http://akka.io"))
responseFuture onComplete {
case Success(res) => println(res)
case Failure(t) => println("An error has occured: " + t.getMessage)
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With