2015-08-27 4 views
7

Unten finden Sie einen einfachen Actor, der einen HTTP-Aufruf benötigt, um Daten von einer API zu empfangen. Gemäß der Akka HTTP Core Request-Level Client-Side API werden nur die ActorSystem und ActorMaterializer implizit benötigt.Ist es möglich, eine Akka HTTP Core Client Anfrage in einem Actor zu machen?

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) 
     } 
    } 
    } 
} 

jedoch beim Versuch, die Anwendung, die ich erhalte die folgende Fehlermeldung zu kompilieren:

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 { 

Ist dies der richtige Weg, um einen HTTP-Aufruf innerhalb eines Akka Schauspielers zu machen?

bearbeiten

import ExecutionContext.Implicits.global inklusive die letzten beiden ExecutionContext Fehler zu beheben.

Antwort

10

Zum Erstellen des ActorMaterializers ist eine implizite ActorRefFactory erforderlich. Die im Merkmal "Akteur" definierte Kontexteigenschaft erweitert ActorRefFactory und ist implizit. Die Systemeigenschaft für Kontext, die Sie explizit importiert haben, ist ein weiterer impliziter Kandidat für ActorRefFactory, da ActorSystem ActorRefFactory erweitert.

Mein Vorschlag ist, den Import zu entfernen und ihn explizit dorthin zu geben, wo er benötigt wird.

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) 
     } 
    } 
    } 
} 
Verwandte Themen