Jay Taylor's notes
back to listing indexspray | Documentation » 1.1-SNAPSHOT » spray-routing
[web search]
Original source (spray.io)
Clipped on: 2014-02-21
spray-routing
The spray-routing module provides a high-level, very flexible routing DSL for elegantly defining RESTful web services. Normally you would use it either on top of a spray-can HTTP Server or inside of a servlet container together with spray-servlet.
Minimal Example
This is a complete, very basic spray-routing application:
import spray.routing.SimpleRoutingApp object Main extends App with SimpleRoutingApp { implicit val system = ActorSystem("my-system") startServer(interface = "localhost", port = 8080) { path("hello") { get { complete { <h1>Say hello to spray</h1> } } } } }
It starts a spray-can HTTP Server on localhost and replies to GET requests to /hello with a simple response.
Longer Example
The following is a spray-routing route definition that tries to show off a few features. The resulting service does not really do anything useful but its definition should give you a feel for what an actual API definition with spray-routing will look like:
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 { // decompresses the request with Gzip or Deflate when required decompressRequest() { // unmarshal with in-scope unmarshaller entity(as[Order]) { order => // transfer to newly spawned actor detach() { complete { // ... write order to DB "Order received" } } } } } } } ~ // extract URI path element as Int pathPrefix("order" / IntNumber) { orderId => pathEnd { // 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]) { completer => ctx => processOrderRequest(orderId, completer) } } } } ~ 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) { // optionally compresses the response with Gzip or Deflate // if the client accepts compressed responses compressResponse() { // serve up static content from a JAR resource getFromResourceDirectory("docs") } } } ~ path("oldApi" / Rest) { pathRest => redirect("http://oldapi.example.com/" + pathRest, StatusCodes.MovedPermanently) } } }