繁体   English   中英

Akka-Http DSL 中发生了什么?

[英]What Happend In Akka-Http DSL?

最近刚接触akka,在学习akka-http的时候,被Rest API 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”方法也是一个指令,但我无法理解一个指令如何通过大括号“{}”“嵌入”到另一个指令中。

我知道,肯定有一些隐式转换,通过调试,我看到,应用了以下隐式转换: akka.http.scaladsl.server.Directive#addByNameNullaryApply

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

任何人都可以向我解释:如何选择并发生这种隐式转换? apply 和 tapply 尝试做什么? 非常感谢!

第一的:

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]

Flow[HttpRequest, HttpResponse, NotUsed]隐式转换routeRouteResult.route2HandlerFlow实现。 这由Directives扩展并与import akka.http.scaladsl.server.Directives._

因此,当您导入 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的类型是Directive0 ,所以:

implicit def addByNameNullaryApply(directive: Directive0): (⇒ Route) ⇒ Route用于将Directive0类型转换为类型为(⇒ Route) ⇒ Route高阶函数

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM