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
第一种状况至关清楚,经过调用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容许你经过组合简单的路由来构造更复杂的路由。 文档
用简单路由构造复杂路由有三个基本的操做:
最后一点经过简单的~操做来完成,它对全部路由都有效,例如一个隐式的“扩展”。前两点由Directives来提供,spray-routing已经预约义了大多数,你也能够本身简单地建立。Directives给予spray-routing大部分能力和灵活性。
基本上,当你经过嵌套和~操做来结合指令和自定义路由时,你构造了一个树形路由结构。当一个请求到来,它被注入到树的根,并以深度优先的方式向下流经全部分支,直到有节点完成,或所有拒绝。
考虑这个例子:
val route = a { b { c { ... // route 1 } ~ d { ... // route 2 } ~ ... // route 3 } ~ e { ... // route 4 } }有5个构成路由树的指令。
路由3所以能够被视为一种“全方位”路由(若是路由连接前面的位置拒绝)。这种机制可使复杂的过滤逻辑很容易实现:简单地把最具体的状况提早并把通常状况放后面。