- Spray should be run standalone in spray-can, since you don't want to encapsulate high-performant actor inside a low-performant container
- Spray natively supports Futures:
def getEmployees: Future[List[Employees]] = ???
route = get { complete(OK, getEmployees)}
- Spray runs within one actor. The canonical way to write Spray directives is to write non-blocking directives rather than using more actors.
- Spray has a long-list of built-in directives. Check them out.
- Directives can be chained with
&
. For example
(decompressRequest() & compressResponseIfRequested()) {...}
- Spray 1.* has a confusing behaviour. Running the following:
val route: Route = get {
println("Hello");
complete("world!")
}
will print Hello at the beginning of the program, instead of at each get request. This is because the inner code is a function which will be creating at start:
val inner = {
println("Hello");
complete("world!")
}
val route: Route = get inner
Will be fixed in Spray 2.0
-
Dealing with failures:
- If a directive is not matched, it returns a
Rejection
. If all directives returns a Rejection, the most concrete rejection is returned - Error message can be customized by providing your own
RejectionHandler
- Rejections can be tested against, you can check on the
rejection
object within the unit tests - similarly, there is a default
ExceptionHandler
and you can write custom rejection handler
- If a directive is not matched, it returns a
-
Spray is integrated with spray-json:
- Error in json unmarshalling throws an Exception. Spray engine turns it into
Rejection
- Error in json unmarshalling throws an Exception. Spray engine turns it into