spray路由
spray-routing模块提供一个高级的,很灵活的路由DSL,来定义RESTful web服务。通常将它用在spray-can HttpServer之上,或在servlet容器内和spray-servlet一起用。
最小的示例
这是一个完整的,基本的spray-routing应用:
import spray.routing.SimpleRoutingApp
object Main extends App with SimpleRoutingApp {
startServer(interface = "localhost", port = 8080) {
path("hello") {
get {
complete {
<h1>Say hello to spray</h1>
}
}
}
}
}
它在本地启动一个spray-can
HttpServer 并给GET请求/hello 回复一个简单的响应。
更长的示例
以下是一个spray-routing路由定义,它试图展示几个特性。由此产生的服务并不真的做有用的事情,但是它的定义应该能给你一个感觉,用spray-routing定义的实际API看起来是这样的:
import scala.concurrent.duration.Duration
import spray.routing.HttpService
import spray.routing.authentication.BasicAuth
import spray.routing.directives.CachingDirectives._
import spray.httpx.encoding._
trait LongerService extends HttpService with MyApp {
val simpleCache = routeCache(maxCapacity = 1000, timeToIdle = Duration("30 min"))
val route = {
path("orders") {
authenticate(BasicAuth(realm = "admin area")) { user =>
get {
cache(simpleCache) {
encodeResponse(Deflate) {
complete {
// marshal custom object with in-scope marshaller
getOrdersFromDB
}
}
}
} ~
post {
(decodeRequest(Gzip) | decodeRequest(NoEncoding)) {
// unmarshal with in-scope unmarshaller
entity(as[Order]) { order =>
// transfer to newly spawned actor
detachTo(singleRequestServiceActor) {
complete {
// ... write order to DB
"Order received"
}
}
}
}
}
}
} ~
// extract URI path element as Int
pathPrefix("order" / IntNumber) { orderId =>
path("") {
// method tunneling via query param
(put | parameter('method ! "put")) {
// form extraction from multipart or www-url-encoded forms
formFields('email, 'total.as[Money]).as(Order) { order =>
complete {
// complete with serialized Future result
(myDbActor ? Update(order)).mapTo[TransactionResult]
}
}
} ~
get {
// JSONP support
jsonpWithParameter("callback") {
// use in-scope marshaller to create completer function
produce(instanceOf[Order]) { complete => ctx =>
processOrderRequest(orderId, complete)
}
}
}
} ~
path("items") {
get {
// parameters to case class extraction
parameters('size.as[Int], 'color ?, 'dangerous ? "no")
.as(OrderItem) { orderItem =>
// ... route using case class instance created from
// required and optional query parameters
}
}
}
} ~
path("documentation") {
// cache responses to GET requests
cache(simpleCache) {
// serve up static content from a JAR resource
encodeResponse(Gzip) {
getFromResourceDirectory("docs")
}
}
} ~
path("oldApi" / Rest) { path =>
redirect("http://oldapi.example.com/" + path)
}
}
}