What is spray?
We believe that, having chosen Scala (and possibly Akka) as primary tools for building software, you’ll want to rely on their power not only in your application layer but throughout the full (JVM-level) network stack. spray provides just that: a set of integrated components for all your REST/HTTP needs that let you work with idiomatic Scala (and Akka) APIs at the stack level of your choice, all implemented without any wrapping layers around “legacy” Java libraries.
sprays development is guided by the following principles:
- Fully asynchronous, non-blocking
- All APIs are fully asynchronous, blocking code is avoided wherever at all possible.
- Actor- and Future-based
- spray fully embraces the programming model of the platform it is built upon. Akka Actors and Futures are key constructs of its APIs.
- Especially sprays low-level components are carefully crafted for excellent performance in high-load environments.
- All dependencies are very carefully managed, sprays codebase itself is kept as lean as possible.
- Being structured into a set of integrated but loosely coupled components your application only needs to depend onto the parts that are actually used.
- All spray components are structured in a way that allows for easy and convenient testing.
Currently the spray suite consists of these modules:
- Fast and lightweight in-memory caching built upon concurrentlinkedhashmap and Akka Futures.
- A low-level, low-overhead, high-performance HTTP server and client built on top of spray-io.
- Provides client-side HTTP support at a higher level than the low-level spray-can HTTP Client APIs, which it builds on.
- An immutable model of HTTP requests, responses and common headers. This module is completely stand-alone, it neither depends on Akka nor on any other part of spray.
- Higher-level tools for working with HTTP messages (mainly marshalling, unmarshalling and (de)compression) that are used by both spray-client as well as spray-routing.
- A low-level network IO layer for directly connecting Akka actors to asynchronous Java NIO sockets. We like to think of it a basic version of Netty for Scala. As of 1.0-M8/1.1-M8 it contains a backport of the new Akka IO layer coming with Akka 2.2. In 1.2-M8 it merely contains a few spray-specific “left-overs” that will likely go away completely in the future.
- An adapter layer providing (a subset of) the spray-can HTTP Server interface on top of the Servlet API. Enables the use of spray-routing in a servlet container.
- A high-level routing DSL for elegantly defining RESTful web services.
- A DSL for easily testing spray-routing services. Supports both ScalaTest as well as Specs2.
- Small utility module used by all other modules except spray-http.
- A lightweight, clean and simple JSON implementation in Scala. Because it neither depends on any other part of spray nor on Akka and is only an optional dependency of spray-client and spray-httpx it doesn’t live in the main spray repository, but rather in its own github repository Note that you can easily use spray with whatever JSON library you like best, spray-json is just one of several alternatives.
Since its inception in early 2011 sprays development has been driven with a clear focus on providing tools for building integration layers rather than application cores. As such it regards itself as a suite of libraries rather than a framework.
A framework, as we’d like to think of the term, gives you a “frame”, in which you build your application. It comes with a lot of decisions already pre-made and provides a foundation including support structures that lets you get started and deliver results quickly. In a way a framework is like a skeleton onto which you put the “flesh” of your application in order to have it come alive. As such frameworks work best if you choose them before you start application development and try to stick to the frameworks “way of doing things” as you go along.
For example, if you are building a browser-facing web application it makes sense to choose a web framework and build your application on top of it because the “core” of the application is the interaction of a browser with your code on the web-server. The framework makers have chosen one “proven” way of designing such applications and let you “fill in the blanks” of a more or less flexible “application-template”. Being able to rely on best-practice architecture like this can be a great asset for getting things done quickly.
spray was designed specifically as “not-a-framework”, not because we don’t like frameworks, but for use cases where a framework is not the right choice. spray is made for building integration layers based on HTTP and as such tries to “stay on the sidelines”. Therefore you normally don’t build your application “on top of” spray, but you build your application on top of whatever makes sense and use spray merely for the HTTP integration needs.