Skip to content
sirthias edited this page Nov 17, 2012 · 43 revisions



This documentation is for release 0.9.0, which is built against Scala 2.9.1 and Akka 1.3.1 (see Requirements for more information). Please turn to the main spray site at http://spray.io for more information about other available versions.



spray

spray is a suite of lightweight Scala libraries for building and consuming RESTful web services on top of Akka. It sports the following main features:

  • Completely asynchronous, non-blocking, actor-based request and response processing for efficiently handling very high numbers of concurrent connections
  • Powerful, flexible and extensible internal Scala DSL for declaratively defining your web service behavior
  • Immutable model of the HTTP protocol, decoupled from the underlying web server / servlet container
  • Full testability of your REST services, without the need to fire up containers or actors

Currently spray consists of the following components:

  • spray-can, a low-level, low-overhead, high-performance, fully asynchronous HTTP/1.1 server and client (ScalaDoc)
  • , a high-level routing DSL for elegantly defining RESTful web services (ScalaDoc)
  • spray-client, a layer on top of the low-level spray-can HttpClient offering higher-level client functionality (ScalaDoc)
  • spray-json, a lightweight, clean and simple JSON implementation in Scala (ScalaDoc)

spray-server and spray-client share one github repository (this one), whereas spray-can and spray-json live in their own.

Very Basic spray-server Example

import cc.spray._

trait HelloService extends Directives {
  val helloService = {
    path("hello") {
      get {
        completeWith {
          <h1>Say hello to Spray</h1>
        }
      }
    }
  }
}

Blog Posts

The following posts have already gathered some dust, we'll resume writing about spray for the coming 1.0 milestones.

Support, Feedback, General Discussion

Please use the active http://groups.google.com/group/spray-user/ mailing list for all your concerns! You should also follow us on twitter: @spraycc

Longer Sample Code

The following is a spray-server web service definition that tries to show off a few of sprays features. The resulting service does not really do anything useful but its definition should give you a pretty good idea of what is possible with spray:

val service = {
  path("orders") {
    authenticate(httpBasic(realm = "admin area")) { user =>
      get {
        cacheResults(LruCache(maxCapacity = 1000, timeToIdle = Some(30.minutes))) {
          encodeResponse(Deflate) {
            completeWith {
              // marshal custom object with in-scope marshaller
              getOrdersFromDB
            }
          }
        }
      } ~
      post {
        (decodeRequest(Gzip) | decodeRequest(NoEncoding)) {
          // unmarshal with in-scope unmarshaller
          content(as[Order]) { order =>
            // transfer to newly spawned actor
            detach {
              completeWith {
                // ... 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 =>
          completeWith {
            // 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 =>
            _ => complete(getOrderFromDB(orderId))
          }
        }
      }                
    } ~
    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 {
      // serve up static content from a JAR resource
      encodeResponse(Gzip) {
        getFromResourceDirectory("docs")
      }
    }
  } ~
  path("oldApi" / Remaining) { path =>
    redirect("http://oldapi.example.com/" + path)
  }
}

License

spray is released under the Apache License 2.0.

Portions of the immutable HTTP model are
copyright (C) 2010-2011 by the BlueEyes Web Framework Team

Clone this wiki locally