2017-04-18 19 views
0

這更多的是一個Scala問題,但受此http-scala示例的啓發。路徑方法如何在akka-http中工作

val route = 
     path("hello") { 
     get { 
      complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, "<h1>Say hello to akka-http</h1>")) 
     } 
     } 

基於例如path似乎是它可以成爲一個令行禁止方法,該方法String作爲第一個參數,作爲Route第二,雖然我沒有看到API在這樣的實現。有人能告訴我這是如何工作的嗎?

鏈接到文檔:http://doc.akka.io/api/akka-http/current/akka/http/javadsl/server/Directives $ .html#path(segment:String,inner:java.util.function.Supplier [akka.http.javadsl.server.Route]):akka.http.javadsl.server.Route

回答

2

不,path不是咖喱功能。該API給出了簽名:

def path[L](pm: PathMatcher[L]): Directive[L] 

Path是一個簡單的一元函數,它在PathMatcher和返回指令。路徑似乎只是一個咖喱功能,因爲Directivean apply method這使得它看起來是一個函數,但它實際上是一個類。

的PathMatcher

通過導入Directives._以下隱函數變得可用:

implicit def _segmentStringToPathMatcher(segment: String): PathMatcher0 

注:PathMatcher0定義爲PathMatcher[Unit],因爲它不沿所述內Route通過匹配的值。

調用與在該示例中,path("hello")參數路徑,類似於下面的代碼:

val directive : Directive[Unit] = path(_segmentStringToPathMatcher("hello")) 

指令

如前所述,所述Directive具有應用方法,該方法懶惰地發生在一個路線:

def apply(v1 : => Route) : Route 

所以你的例子代碼本質上是馬王以下電話:

val route = 
    directive.apply(get { 
        complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, "<h1>Say hello to akka-http</h1>")) 
        }) 

全部放在一起

讓我們簡化Route定義和嘲笑一些邏輯來證明所發生的事情:

type SimpleRoute : HttpRequest => RouteResult 

現在,我們可以寫一個使用更高階函數的路徑版本。我們更簡單的版本需要String並返回一個函數而不是一個指令。它有點棘手,因爲返回的功能也是更高的順序:

def simplePath(pathStr : String) : SimpleRoute => SimpleRoute = 
    (innerRoute : SimpleRoute) => { 

    //this is the returned SimpleRoute 
    (request : HttpRequest) => { 
     if(request.uri.path.toString equalsIgnoreCase pathStr) 
     RouteResult.Complete(innerRoute(request)) 
     else 
     RouteResult.Rejected(Seq.empty[Rejection]) 
    } 

    }