2016-10-26 9 views
1

я просто прикоснулся Аккой в ​​последнее время, когда обучение Акки-клиент, я привлекаю API DSL Rest, вот кусок коды:Что такое Happend в Akka-Http DSL?

import akka.actor.ActorSystem 
import akka.http.scaladsl.Http 
import akka.http.scaladsl.model._ 
import akka.http.scaladsl.server.Directives._ 
import akka.stream.ActorMaterializer 
import scala.io.StdIn 

object WebServer { 
    def main(args: Array[String]) { 
     implicit val system = ActorSystem("my-system") 
     implicit val materializer = ActorMaterializer() 
     // needed for the future flatMap/onComplete in the end 
     implicit val executionContext = system.dispatcher 
     val route = 
     path("hello") { 
      get { 
       complete("Say hello to akka-http") 
      } 
     } 
     val bindingFuture = Http().bindAndHandle(route, "localhost", 8080) 
     println(s"Server online at http://localhost:8080/\nPress RETURN to stop...") 
     StdIn.readLine() // let it run until user presses return 
     bindingFuture 
     .flatMap(_.unbind()) // trigger unbinding from the port 
     .onComplete(_ => system.terminate()) // and shutdown when done 
    } 
} 

То, что я не могу понять это val route = path("hello") {....}. Я знаю, что метод «путь» вернет директиву, а метод «get» также является директивой, но я не могу понять, как директива «встраивается» в другую директиву скобками «{}».

Я знаю, что должно быть некоторые неявные преобразования, по отладке, я увидел следующее неявное преобразование применяется: akka.http.scaladsl.server.Directive#addByNameNullaryApply

implicit def addByNameNullaryApply(directive: Directive0): (⇒ Route) ⇒ Route = 
    r ⇒ directive.tapply(_ ⇒ r) 

Может кто-нибудь объяснить мне: как это неявное преобразование выбрано и произошло ? И какую дозу применять и нажимать попытаться? Большое спасибо!

ответ

4

Первое:

val bindingFuture = Http().bindAndHandle(route, "localhost", 8080) 

равно:

val bindingFuture = Http().bindAndHandle(Route.handlerFlow(route), "localhost", 8080) 

метод Route.handlerFlow используется для преобразования Route в Flow[HttpRequest, HttpResponse, NotUsed], как мы видим bindAndHandle принять handler тип является: Flow[HttpRequest, HttpResponse, Any]

неявный диалог ионroute до Flow[HttpRequest, HttpResponse, NotUsed] реализован RouteResult.route2HandlerFlow. и это распространяется на Directives и работает с import akka.http.scaladsl.server.Directives._.

поэтому, когда вы Директивы импорта, вы импортируете это неявные преобразования.

Для addByNameNullaryApply, мы можем переписать код, как ниже:

... 
val path1: Directive0 = path("hello") 
val contextToEventualResult: Route = get(complete("Say hello to akka-http")) 
val route: Route = path1.apply(contextToEventualResult) 
... 

, как мы видим, для path1.apply(contextToEventualResult) это вызовом функции в высокого порядка с применением contextToEventualResult параметра. но для типа path1 «S является Directive0, так что:

implicit def addByNameNullaryApply(directive: Directive0): (⇒ Route) ⇒ Route используется для преобразования Directive0 типа с функцией в высокого порядка с типом: (⇒ Route) ⇒ Route.

+0

спасибо за входные данные, что я действительно хочу знать: 'val route = path (" hello ") {....}', как я сказал в своем сообщении, он применял неявное преобразование: addByNameNullaryApply, можете ли вы помочь объясните эту часть? –

+0

@LaurenceGeng извините недоразумение вопрос, я добавил * addByNameNullaryApply * информация, надеюсь, это полезно для вас. – chengpohi

+0

Привет Chengpohi, с разбивкой статусы более ясны сейчас, спасибо. Можете ли вы объяснить 'r' и' _' в 'r ⇒ directive.tapply (_ ⇒ r)'? –