spray-routing - 路由

spray.io的文檔太晦澀,啃起來太痛苦了。還有,屋裏真冷。
路由

「路由」是spray-routing的中心概念,由於全部你用DSL建立的結構都是Route的子類型。在spray-routing中一個路由須要以下方式定義: html

type Route = RequestContext => Unit

它是一個把RequestContext做爲參數的函數的別名。 函數

不一樣於你最初所指望的,一個路由不返回任何東西。相反,全部響應處理(在路由處理完一個請求後須要完成的全部事情)是經過 RequestContext的響應器來執行的(in 「continuation-style」)。若是你不知道這意味着什麼的話,別擔憂。這些很快就會變得清晰。關鍵是,這種設計的優勢是徹底非阻塞以及 Actor友好的,由於這種方式,它能夠簡單地把一個RequestContext發送給另外一個Actor(以「fire-and-forget」的方 式),而沒必要擔憂結果處理。 this

一般當一個路由接收到一個請求(或者說是一個RequestContext)它能夠作這三件事中的一個: spa

  • 經過調用requestContext.complete(...)完成這個請求
  • 經過調用requestContext.reject(...)拒絕這個請求
  • 忽略這個請求(既不完成也不拒絕)

第一種狀況至關清楚,經過調用complete將一個給定的響應發送到客戶端做爲這個請求的反應。第二種狀況中,「拒絕」意味着路由不想處理這個請 求。You’ll see further down in the section about route composition what this is good for。第三種狀況一般是一個錯誤。若是一個路由對請求不作任何事情,它會簡單的不對它產生做用。這意味着客戶端將接收不到響應,直到請求超時,此時會生 成一個「500 Internal Server Error 」響應。所以你的路由一般以完成或拒絕請求來結束。 scala

構造路由

路由是普通的函數(RequestContext => Unit),最簡單的路由是: 設計

ctx => ctx.complete("Response")

更簡短的: code

_.complete("Response")

還有更短的(用complete指令): htm

complete("Response")

這些都是不一樣的方式定義相同的東西,即一個路由用一個靜態響應簡單地完成全部請求。 路由

雖然你能夠把全部應用邏輯寫到一個函數裏,來檢查RequestContext並根據它的屬性來完成它,但這種設計很難閱讀,維護和重用。所以spray-routing容許你經過組合簡單的路由來構造更復雜的路由。 文檔

組合路由

用簡單路由構造複雜路由有三個基本的操做:

  • 路由轉換,which delegates processing to another, 「inner」 route but in the process changes some properties of either the incoming request, the outgoing response or both(什麼意思???)
  • 路由過濾,只容許知足給定過濾器條件的請求經過,並拒絕其餘全部的
  • 路由鏈,若是第一個路由拒絕了,它會嘗試第二個

最後一點經過簡單的~操做來完成,它對全部路由都有效,例如一個隱式的「擴展」。前兩點由Directives來提供,spray-routing已經預約義了大多數,你也能夠本身簡單地建立。Directives給予spray-routing大部分能力和靈活性。

路由樹

基本上,當你經過嵌套和~操做來結合指令和自定義路由時,你構造了一個樹形路由結構。當一個請求到來,它被注入到樹的根,並以深度優先的方式向下流經全部分支,直到有節點完成,或所有拒絕。

考慮這個例子:

val route =
  a {
    b {
      c {
        ... // route 1
      } ~
      d {
        ... // route 2
      } ~
      ... // route 3
    } ~
    e {
      ... // route 4
    }
  }
有5個構成路由樹的指令。
  • 路由1僅在指令a,b和c都經過時可達。
  • 若是a,b經過,c拒絕而且d經過,將運行路由2。
  • 若是a和b經過,但c和d拒絕,將運行路由3。

路由3所以能夠被視爲一種「全方位」路由(若是路由連接前面的位置拒絕)。這種機制可使複雜的過濾邏輯很容易實現:簡單地把最具體的狀況提早並把通常狀況放後面。

相關文章
相關標籤/搜索