2016-10-26 10 views
1

私は最近アッカ触れ、アッカ-HTTPを学習するとき、私は残りのAPIのDSLによって惹か、ここでのコードの一部です: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") {....}です。 "path"メソッドはディレクティブを返し、 "get"メソッドもディレクティブですが、ディレクティブが中括弧 "{}"で他のディレクティブにどのように埋め込まれるのか理解できません。

I知っている、デバッグによって、いくつかの暗黙の変換がなければならない、私が見た、以下の暗黙的な変換が適用されます。akka.http.scaladsl.server.Directive#addByNameNullaryApply

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

誰が私に説明できます:どのようにこの暗黙の型変換を選択して起こっていることができます?そして、どのような用量を適用し、tapplyしようとする?どうもありがとう!

答えて

4

まず:

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

はに等しい:

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

Route.handlerFlow方法は、我々はbindAndHandlehandlerタイプを受け入れる見るようである、Flow[HttpRequest, HttpResponse, NotUsed]に変換Routeに使用される:Flow[HttpRequest, HttpResponse, Any]

暗黙の会話イオンrouteFlow[HttpRequest, HttpResponse, NotUsed]は、RouteResult.route2HandlerFlowによって実装されています。これはDirectivesで拡張され、import akka.http.scaladsl.server.Directives._で動作します。

のインポート指示をインポートすると、この暗黙の変換がインポートされます。

addByNameNullaryApplyのために、私たちは以下のようにコードを書き換えることができます。私たちが見ることができるよう、path1.apply(contextToEventualResult)ことがcontextToEventualResultパラメータを適用して高次関数を呼んだ

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

。しかしpath1のタイプのためにそう、Directive0ある:(⇒ Route) ⇒ Route

implicit def addByNameNullaryApply(directive: Directive0): (⇒ Route) ⇒ Route型と高階関数Directive0タイプを変換するために使用されます。

+0

私が本当に知りたいのは、val route = path( "hello"){....} 'です。私の記事では暗黙的な変換を適用しました:addByNameNullaryApplyこの部分を説明する? –

+0

@LaurenceGeng申し訳ありませんが間違いの質問、私は* addByNameNullaryApply *説明を追加しました、有望なあなたのために役立つ。 – chengpohi

+0

こんにちはChengpohi、崩壊の文章は、今、より感謝しています。あなたは 'r⇒directive.tapply(_⇒r)'で 'r'と' _'を説明できますか? –

関連する問題