REST on Akka	

!

Antoine Comte	

Twitter : @comte_a	

antoine.comte@gmail.com	

Slidedeck courtesy of the Spray team
What is spray?
Suite of libraries for building and consuming
RESTful web services on top of Akka	


• First released about...
Components
• Rich immutable HTTP model	

• spray-server:


DSL for server-side API construction	


• spray-client: complem...
spray-server
• Runs on servlet containers or spray-can	

• Tool for building a “self-contained” API layer	

• Central elem...
Basic Architecture
Application

Business	

Logic
Basic Architecture
REST API layer

Application

HTTP Request

Routing	

Logic

Business	

Logic
Basic Architecture
REST API layer

HTTP Request

Action

Routing	

Logic

HTTP Response

Application

domain
object !
Repl...
API Layer Responsibilities
• Request routing based on method, path,
query parameters, entity	


• (Un)marshalling to / fro...
Route Example
A simple spray route:	

!

val route: Route =
path("order" / HexIntNumber) { id =>
get {
completeWith {
"Rec...
Routing Basics
Routes in spray:	

type Route = RequestContext => Unit

!

Central object:	

case class RequestContext(
req...
Routing Basics
The simplest route:	

ctx => ctx.complete("Say hello to spray")

or:	

_.complete("Say hello to spray")

or...
Directives
Route structure built with directives:	

!

val route: Route =
path("order" / HexIntNumber) { id =>
get {
compl...
Directives
Compiles?

Operators are type-safe:	

val orderPath = path("order" / IntNumber)
val dir = orderPath | get
val d...
Directives



spray 1.2 comes with 110 predefined directives:

alwaysCache, anyParam, anyParams, authenticate, authorize, a...
Real World Example
lazy val route = {
encodeResponse(Gzip) {
path("") {
get {
redirect("/doc")
}
} ~
pathPrefix("api") {
js...
Best Practices
• Keep route structure clean and readable,

pull out all logic into custom directives	


• Don’t let API la...
There is more ...
• SprayJsonSupport, LiftJsonSupport,
TwirlSupport, ScalateSupport	


• Asynchronous response push stream...
Current State
• spray 1.2-RC2 just released

• Coming features: new documentation site,
deeper REST support, monitoring, r...
A few current sprayers ...
Getting started
• Main site & documentation:

http://spray.io/	


• Mailing list:


http://groups.google.com/group/spray-u...
Thank you!
Upcoming SlideShare
Loading in …5
×

Spray human talks

1,059 views

Published on

Une présentation de Spray au HumanTalks de Genève

Published in: Technology
  • Be the first to comment

Spray human talks

  1. 1. REST on Akka ! Antoine Comte Twitter : @comte_a antoine.comte@gmail.com Slidedeck courtesy of the Spray team
  2. 2. What is spray? Suite of libraries for building and consuming RESTful web services on top of Akka • First released about 2 year ago • Principles: lightweight, async, non-blocking, actor-based, modular, few deps, testable • Philosophy: library, not framework
  3. 3. Components • Rich immutable HTTP model • spray-server:
 DSL for server-side API construction • spray-client: complementary HTTP client • spray-can: low-level HTTP server and client • spray-json: straight JSON in scala (no Akka)
  4. 4. spray-server • Runs on servlet containers or spray-can • Tool for building a “self-contained” API layer • Central element:
 Routing DSL for defining web API behavior • Focus: RESTful web API, not web GUI
  5. 5. Basic Architecture Application Business Logic
  6. 6. Basic Architecture REST API layer Application HTTP Request Routing Logic Business Logic
  7. 7. Basic Architecture REST API layer HTTP Request Action Routing Logic HTTP Response Application domain object ! Reply Business Logic
  8. 8. API Layer Responsibilities • Request routing based on method, path, query parameters, entity • (Un)marshalling to / from domain objects • Encoding / decoding • Authentication / authorization • Caching and serving static content • RESTful error handling
  9. 9. Route Example A simple spray route: ! val route: Route = path("order" / HexIntNumber) { id => get { completeWith { "Received GET request for order " + id } } ~ put { completeWith { "Received PUT request for order " + id } } }
  10. 10. Routing Basics Routes in spray: type Route = RequestContext => Unit ! Central object: case class RequestContext( request: HttpRequest, ...) {   def complete(...) { ... }   def reject(...) { ... }   ... } Explicit continuation-
 passing style
  11. 11. Routing Basics The simplest route: ctx => ctx.complete("Say hello to spray") or: _.complete("Say hello to spray") or using a “directive”: completeWith("Say hello to spray") def completeWith[T :Marshaller](value: => T): Route = _.complete(value)
  12. 12. Directives Route structure built with directives: ! val route: Route = path("order" / HexIntNumber) { id => get { completeWith { "Received GET request for order " + id } } ~ put { completeWith { "Received PUT request for order " + id } } } extractions directive name args route concatenation: recover from rejections Route structure forms a tree! inner route
  13. 13. Directives Compiles? Operators are type-safe: val orderPath = path("order" / IntNumber) val dir = orderPath | get val dir = orderPath | path("[^/]+".r / DoubleNumber) val dir = orderPath | parameter('order.as[Int]) val order = orderPath & parameters('oem, 'expired ?) val route = order { (orderId, oem, expired) => ... // inner route }
  14. 14. Directives 
 spray 1.2 comes with 110 predefined directives:
 alwaysCache, anyParam, anyParams, authenticate, authorize, autoChunk, cache, cachingProhibited, cancelAllRejections, cancelRejection, clientIP, complete, compressResponse, compressResponseIfRequested, cookie, decodeRequest, decompressRequest, delete, deleteCookie, detach, dynamic, dynamicIf, encodeResponse, entity, extract, failWith, formField, formFields, get, getFromBrowseableDirectories, getFromBrowseableDirectory, getFromDirectory, getFromFile, getFromResource, getFromResourceDirectory, handleExceptions, handleRejections, handleWith, head, headerValue, headerValueByName, headerValuePF, hextract, host, hostName, hprovide, jsonpWithParameter, listDirectoryContents, logRequest, logRequestResponse, logResponse, mapHttpResponse, mapHttpResponsePart, mapHttpResponseEntity, mapHttpResponseHeaders, mapInnerRoute, mapRejections, mapRequest, mapRequestContext, mapRouteResponse, mapRouteResponsePF, method, overrideMethodWithParameter, noop, onComplete, onFailure, onSuccess, optionalCookie, optionalHeaderValue, optionalHeaderValueByName, optionalHeaderValuePF, options, parameter, parameterMap, parameterMultiMap, parameters, parameterSeq, pass, patch, path, pathPrefix, pathPrefixTest, pathSuffix, pathSuffixTest, post, produce, provide, put, redirect, reject, rejectEmptyResponse, requestEncodedWith, requestEntityEmpty, requestEntityPresent, respondWithHeader, respondWithHeaders, respondWithLastModifiedHeader, respondWithMediaType, respondWithSingletonHeader, respondWithSingletonHeaders, respondWithStatus, responseEncodingAccepted, rewriteUnmatchedPath, routeRouteResponse, scheme, schemeName, setCookie, unmatchedPath, validate
  15. 15. Real World Example lazy val route = { encodeResponse(Gzip) { path("") { get { redirect("/doc") } } ~ pathPrefix("api") { jsonpWithParameter("callback") { path("top-articles") { get { parameter('max.as[Int]) { max => validate(max >= 0, "query parameter 'max' must be >= 0") { completeWith { (topArticlesService ? max).mapTo[Seq[Article]] } } } } } ~ tokenAuthenticate { user => path("ranking") { get { countAndTime(user, "ranking") { parameters('fixed ? 0, 'mobile ? 0, 'sms ? 0, 'mms ? 0,
  16. 16. Best Practices • Keep route structure clean and readable,
 pull out all logic into custom directives • Don’t let API layer leak into application • Use (Un)marshalling infrastructure • Wrap blocking code with `detach` • Use sbt-revolver + JRebel for fast dev turnaround
  17. 17. There is more ... • SprayJsonSupport, LiftJsonSupport, TwirlSupport, ScalateSupport • Asynchronous response push streaming • Testing spray routes • RESTful errors • spray-client
  18. 18. Current State • spray 1.2-RC2 just released
 • Coming features: new documentation site, deeper REST support, monitoring, request throttling, and more ...
  19. 19. A few current sprayers ...
  20. 20. Getting started • Main site & documentation:
 http://spray.io/ • Mailing list:
 http://groups.google.com/group/spray-user • Twitter:
 @sprayio
  21. 21. Thank you!

×