SlideShare a Scribd company logo
1 of 88
REST on Akka
⇗ northeast scala symposium
      March 9th, 2012
What is spray?
What is spray?
Suite of libraries for building and consuming
RESTful web services on top of Akka
What is spray?
Suite of libraries for building and consuming
RESTful web services on top of Akka
• First released about 1 year ago
What is spray?
Suite of libraries for building and consuming
RESTful web services on top of Akka
• First released about 1 year ago
• Principles: lightweight, async, non-blocking,
  actor-based, modular, few deps, testable
What is spray?
Suite of libraries for building and consuming
RESTful web services on top of Akka
• First released about 1 year ago
• Principles: lightweight, async, non-blocking,
  actor-based, modular, few deps, testable
• Philosophy: library, not framework
Components
Components
• Rich immutable HTTP model
Components
• Rich immutable HTTP model
• spray-server:
  DSL for server-side API construction
Components
• Rich immutable HTTP model
• spray-server:
  DSL for server-side API construction
• spray-client: complementary HTTP client
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
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)
spray-server
spray-server
• Runs on servlet containers or spray-can
spray-server
• Runs on servlet containers or spray-can
• Tool for building a “self-contained” API layer
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
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
Basic Architecture
   Application




                 Business
                  Logic
Basic Architecture
REST API layer   Application




   Routing
    Logic                      Business
                                Logic
Basic Architecture
          REST API layer   Application


HTTP Request




               Routing
                Logic                    Business
                                          Logic
Basic Architecture
          REST API layer            Application


HTTP Request               Action




               Routing
                Logic                             Business
                                                   Logic
Basic Architecture
          REST API layer            Application


HTTP Request               Action



                           domain
               Routing     object !               Business
                Logic
                                                   Logic
Basic Architecture
          REST API layer            Application


HTTP Request               Action



                           domain
               Routing     object !               Business
                Logic
                                                   Logic

                           Reply
Basic Architecture
          REST API layer            Application


HTTP Request               Action



                           domain
               Routing     object !               Business
                Logic
                                                   Logic

                           Reply
Basic Architecture
          REST API layer            Application


HTTP Request               Action



                           domain
                Routing    object !               Business
                 Logic
                                                   Logic

HTTP Response              Reply
API Layer Responsibilities
API Layer Responsibilities
• Request routing based on method, path,
  query parameters, entity
API Layer Responsibilities
• Request routing based on method, path,
  query parameters, entity
• (Un)marshalling to / from domain objects
API Layer Responsibilities
• Request routing based on method, path,
  query parameters, entity
• (Un)marshalling to / from domain objects
• Encoding / decoding
API Layer Responsibilities
• Request routing based on method, path,
  query parameters, entity
• (Un)marshalling to / from domain objects
• Encoding / decoding
• Authentication / authorization
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
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
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
     }
   }
 }
Routing Basics
Routes in spray:
  type Route = RequestContext => Unit
Routing Basics
Routes in spray:
  type Route = RequestContext => Unit      Explicit
                                        continuation-
                                        passing style
Routing Basics
Routes in spray:
  type Route = RequestContext => Unit      Explicit
                                        continuation-
                                        passing style
Central object:
  case class RequestContext(
    request: HttpRequest,
    ...) {
    def complete(...) { ... }
    def reject(...) { ... }
    ...
  }
Routing Basics
The simplest route:
  ctx => ctx.complete("Say hello to spray")
Routing Basics
The simplest route:
  ctx => ctx.complete("Say hello to spray")


or:
  _.complete("Say hello to spray")
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")
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)
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
     }
   }
 }
Directives
     Route structure built with directives:

     val route: Route =
      path("order" / HexIntNumber) { id =>
        get {
          completeWith {
            "Received GET request for order " + id
          }
directive
        }~
 name   put {
          completeWith {
            "Received PUT request for order " + id
          }
        }
      }
Directives
Route structure built with directives:

val route: Route =
 path("order" / HexIntNumber) { id =>
   get {
     completeWith {
       "Received GET request for order " + id
     }
   }~
                        args
   put {
     completeWith {
       "Received PUT request for order " + id
     }
   }
 }
Directives
Route structure built with directives:

val route: Route =
 path("order" / HexIntNumber) { id =>
   get {                                        extractions
     completeWith {
       "Received GET request for order " + id
     }
   }~
   put {
     completeWith {
       "Received PUT request for order " + id
     }
   }
 }
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
     }
   }                                            inner route
 }
Directives
Route structure built with directives:

val route: Route =
 path("order" / HexIntNumber) { id =>
   get {
     completeWith {
       "Received GET request for order " + id

   }~
     }                route concatenation:
   put {             recover from rejections
     completeWith {
       "Received PUT request for order " + id
     }
   }
 }
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
     }
   }
 }
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
     }
   }                 Route structure
 }
                      forms a tree!
Directives
DRYing up with the `|` operator:

val route =
 path("order" / HexIntNumber) { id =>
   (get | put) { ctx =>
     ctx.complete("Received " + ctx.request.method +
      " request for order " + id)
   }
 }
Directives
Pulling out a custom directive:

val getOrPut = get | put

val route =
 path("order" / HexIntNumber) { id =>
   getOrPut { ctx =>
     ctx.complete("Received " + ctx.request.method +
      " request for order " + id)
   }
 }
Directives
The `&` operator as alternative to nesting:

val getOrPut = get | put

val route =
 (path("order" / HexIntNumber) & getOrPut) { id =>
   ctx =>
    ctx.complete("Received " + ctx.request.method +
            " request for order " + id)
 }
Directives
Pulling out once more:

val orderGetOrPut =
 path("order" / HexIntNumber) & (get | put)

val route =
 orderGetOrPut { id => ctx =>
   ctx.complete("Received " + ctx.request.method +
           " request for order " + id)
 }
Directives
Operators are type-safe:
val orderPath = path("order" / IntNumber)
Directives
 Compiles?
Operators are type-safe:
val orderPath = path("order" / IntNumber)
Directives
 Compiles?
Operators are type-safe:
val orderPath = path("order" / IntNumber)

val dir = orderPath | get
Directives
 Compiles?
Operators are type-safe:
val orderPath = path("order" / IntNumber)

val dir = orderPath | get
Directives
 Compiles?
Operators are type-safe:
val orderPath = path("order" / IntNumber)

val dir = orderPath | get

val dir = orderPath | path("[^/]+".r / DoubleNumber)
Directives
 Compiles?
Operators are type-safe:
val orderPath = path("order" / IntNumber)

val dir = orderPath | get

val dir = orderPath | path("[^/]+".r / DoubleNumber)
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])
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])
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 ?)
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 ?)
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
}
Directives
spray 0.9.0 comes with 69 predefined directives:
alwaysPass, authenticate, authorize, autoChunk, cache, cacheResults, clientIP,
completeWith, content, cookie, decodeRequest, delete, deleteCookie, detach,
dynamic, encodeResponse, filter, filter1, filter2, filter3, filter4, filter5, filter6,
filter7, filter8, filter9, formField, formFields, get, getFromDirectory, getFromFile,
getFromFileName, getFromResource, getFromResourceDirectory, handleWith,
hardFail, head, headerValue, headerValuePF, host, jsonpWithParameter, method,
optionalCookie, options, parameter, parameters, path, pathPrefix, post,
produce, provide, put, redirect, reject, respondWithContentType,
respondWithHeader, respondWithHeaders, respondWithMediaType,
respondWithStatus, setCookie, trace, transformChunkedResponse,
transformRejections, transformRequest, transformRequestContext,
transformResponse, transformRoute, transformUnchunkedResponse, validate
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,
}
       }


 }~
   }
   }
       Real World Example
 tokenAuthenticate { user =>
   path("ranking") {
     get {
       countAndTime(user, "ranking") {
         parameters('fixed ? 0, 'mobile ? 0, 'sms ? 0, 'mms ? 0,
                  'data ? 0).as(RankingDescriptor) { descr =>
           (rankingService ? Ranking(descr)).mapTo[RankingResult]
         }
       }
     }
   }~
   path("accounts") {
     post {
       authorize(user.isAdmin) {
         content(as[AccountDetails]) { details =>
           (accountService ? NewAccount(details)).mapTo[OpResult]
         }
       }
     }
   }~
   path("account" / IntNumber) { accountId =>
     get { ... } ~
     put { ... } ~
     delete { ... }
   }
 }
}~
pathPrefix("v1") {
}
        }~


           Real World Example
        path("account" / IntNumber) { accountId =>
          get { ... } ~
          put { ... } ~
          delete { ... }
        }
          }
        }~
        pathPrefix("v1") {
          proxyToDjango
        }
      }~
      pathPrefix("doc") {
        respondWithHeader(`Cache-Control`(`max-age`(3600))) {
          transformResponse(_.withContentTransformed(markdown2Html)) {
            getFromResourceDirectory("doc/root",
                          pathRewriter = appendFileExt)
          }
        }
      }~
    }~
    cacheIfEnabled {
      encodeResponse(Gzip) {
        getFromResourceDirectory("public")
      }
    }
}
Best Practices
Best Practices
• Keep route structure clean and readable,
  pull out all logic into custom directives
Best Practices
• Keep route structure clean and readable,
  pull out all logic into custom directives
• Don’t let API layer leak into application
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
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`
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 turn-
  around
There is more ...
There is more ...
• SprayJsonSupport, LiftJsonSupport,
  TwirlSupport, ScalateSupport
There is more ...
• SprayJsonSupport, LiftJsonSupport,
  TwirlSupport, ScalateSupport
• Asynchronous response push streaming
There is more ...
• SprayJsonSupport, LiftJsonSupport,
  TwirlSupport, ScalateSupport
• Asynchronous response push streaming
• Testing spray routes
There is more ...
• SprayJsonSupport, LiftJsonSupport,
  TwirlSupport, ScalateSupport
• Asynchronous response push streaming
• Testing spray routes
• RESTful errors
There is more ...
• SprayJsonSupport, LiftJsonSupport,
  TwirlSupport, ScalateSupport
• Asynchronous response push streaming
• Testing spray routes
• RESTful errors
• spray-client
Current State
Current State
• spray 0.9.0 just released
  (last release for Akka 1.x)
Current State
• spray 0.9.0 just released
  (last release for Akka 1.x)
• Current focus: Release first Akka 2.0
  compatible milestone of spray 1.0
Current State
• spray 0.9.0 just released
  (last release for Akka 1.x)
• Current focus: Release first Akka 2.0
  compatible milestone of spray 1.0
• Coming features: new documentation site,
  deeper REST support, monitoring, request
  throttling, and more ...
A few current sprayers ...
Getting started
• Main site & documentation:
  https://github.com/spray/spray/wiki
• Mailing list:
  http://groups.google.com/group/spray-user
• Twitter:
  @spraycc
Thank you!
More
Proxying with spray
Combining with spray-client to build a proxy:
val conduit = new HttpConduit("target.example.com", 8080)

lazy val proxyToTarget: Route = { ctx =>
  ctx.complete {
    conduit.sendReceive {
      ctx.request.withHeadersTransformed {
        _.filter(_.name != "Host")
      }
    }.map {
      _.withHeadersTransformed {
        _.filter(_.name != "Date")
      }
    }
  }

More Related Content

What's hot

Ruby Conf Preso
Ruby Conf PresoRuby Conf Preso
Ruby Conf PresoDan Yoder
 
Onion Architecture and the Blog
Onion Architecture and the BlogOnion Architecture and the Blog
Onion Architecture and the Blogbarryosull
 
Kafka Needs No Keeper
Kafka Needs No KeeperKafka Needs No Keeper
Kafka Needs No KeeperC4Media
 
Web Scale Reasoning and the LarKC Project
Web Scale Reasoning and the LarKC ProjectWeb Scale Reasoning and the LarKC Project
Web Scale Reasoning and the LarKC ProjectSaltlux Inc.
 
Introduction to ACI APIs
Introduction to ACI APIsIntroduction to ACI APIs
Introduction to ACI APIsCisco DevNet
 
How to call REST API without knowing any programming languages
How to call REST API without knowing any programming languages How to call REST API without knowing any programming languages
How to call REST API without knowing any programming languages Marc Leinbach
 
Spark Summit Europe: Building a REST Job Server for interactive Spark as a se...
Spark Summit Europe: Building a REST Job Server for interactive Spark as a se...Spark Summit Europe: Building a REST Job Server for interactive Spark as a se...
Spark Summit Europe: Building a REST Job Server for interactive Spark as a se...gethue
 
Coding 100-session-slides
Coding 100-session-slidesCoding 100-session-slides
Coding 100-session-slidesCisco DevNet
 
05 integrate redis
05 integrate redis05 integrate redis
05 integrate redisErhwen Kuo
 
Above the clouds: introducing Akka
Above the clouds: introducing AkkaAbove the clouds: introducing Akka
Above the clouds: introducing Akkanartamonov
 
Fault Tolerance in Distributed Environment
Fault Tolerance in Distributed EnvironmentFault Tolerance in Distributed Environment
Fault Tolerance in Distributed EnvironmentOrkhan Gasimov
 
Java APIs - the missing manual
Java APIs - the missing manualJava APIs - the missing manual
Java APIs - the missing manualHendrik Ebbers
 
Akka Actor presentation
Akka Actor presentationAkka Actor presentation
Akka Actor presentationGene Chang
 
NGSIv2 Overview for Developers that Already Know NGSIv1
NGSIv2 Overview for Developers that Already Know NGSIv1NGSIv2 Overview for Developers that Already Know NGSIv1
NGSIv2 Overview for Developers that Already Know NGSIv1FIWARE
 
From Zero to Hero with Kafka Connect
From Zero to Hero with Kafka ConnectFrom Zero to Hero with Kafka Connect
From Zero to Hero with Kafka ConnectDatabricks
 
Livy: A REST Web Service for Spark
Livy: A REST Web Service for SparkLivy: A REST Web Service for Spark
Livy: A REST Web Service for SparkAshish kumar
 
Livy: A REST Web Service For Apache Spark
Livy: A REST Web Service For Apache SparkLivy: A REST Web Service For Apache Spark
Livy: A REST Web Service For Apache SparkJen Aman
 

What's hot (20)

Ruby Conf Preso
Ruby Conf PresoRuby Conf Preso
Ruby Conf Preso
 
Onion Architecture and the Blog
Onion Architecture and the BlogOnion Architecture and the Blog
Onion Architecture and the Blog
 
Kafka Needs No Keeper
Kafka Needs No KeeperKafka Needs No Keeper
Kafka Needs No Keeper
 
Web Scale Reasoning and the LarKC Project
Web Scale Reasoning and the LarKC ProjectWeb Scale Reasoning and the LarKC Project
Web Scale Reasoning and the LarKC Project
 
Introduction to ACI APIs
Introduction to ACI APIsIntroduction to ACI APIs
Introduction to ACI APIs
 
Rest APIs Training
Rest APIs TrainingRest APIs Training
Rest APIs Training
 
How to call REST API without knowing any programming languages
How to call REST API without knowing any programming languages How to call REST API without knowing any programming languages
How to call REST API without knowing any programming languages
 
Spark Summit Europe: Building a REST Job Server for interactive Spark as a se...
Spark Summit Europe: Building a REST Job Server for interactive Spark as a se...Spark Summit Europe: Building a REST Job Server for interactive Spark as a se...
Spark Summit Europe: Building a REST Job Server for interactive Spark as a se...
 
Coding 100-session-slides
Coding 100-session-slidesCoding 100-session-slides
Coding 100-session-slides
 
Ruby Under The Hood
Ruby Under The HoodRuby Under The Hood
Ruby Under The Hood
 
05 integrate redis
05 integrate redis05 integrate redis
05 integrate redis
 
Above the clouds: introducing Akka
Above the clouds: introducing AkkaAbove the clouds: introducing Akka
Above the clouds: introducing Akka
 
Fault Tolerance in Distributed Environment
Fault Tolerance in Distributed EnvironmentFault Tolerance in Distributed Environment
Fault Tolerance in Distributed Environment
 
Building REST and Hypermedia APIs with PHP
Building REST and Hypermedia APIs with PHPBuilding REST and Hypermedia APIs with PHP
Building REST and Hypermedia APIs with PHP
 
Java APIs - the missing manual
Java APIs - the missing manualJava APIs - the missing manual
Java APIs - the missing manual
 
Akka Actor presentation
Akka Actor presentationAkka Actor presentation
Akka Actor presentation
 
NGSIv2 Overview for Developers that Already Know NGSIv1
NGSIv2 Overview for Developers that Already Know NGSIv1NGSIv2 Overview for Developers that Already Know NGSIv1
NGSIv2 Overview for Developers that Already Know NGSIv1
 
From Zero to Hero with Kafka Connect
From Zero to Hero with Kafka ConnectFrom Zero to Hero with Kafka Connect
From Zero to Hero with Kafka Connect
 
Livy: A REST Web Service for Spark
Livy: A REST Web Service for SparkLivy: A REST Web Service for Spark
Livy: A REST Web Service for Spark
 
Livy: A REST Web Service For Apache Spark
Livy: A REST Web Service For Apache SparkLivy: A REST Web Service For Apache Spark
Livy: A REST Web Service For Apache Spark
 

Viewers also liked

Bruce Power Saver Brochure
Bruce Power Saver BrochureBruce Power Saver Brochure
Bruce Power Saver BrochureSteve Glover
 
EU: Tanks, Casks, Drums, Cans, Boxes And Similar Containers - Market Report. ...
EU: Tanks, Casks, Drums, Cans, Boxes And Similar Containers - Market Report. ...EU: Tanks, Casks, Drums, Cans, Boxes And Similar Containers - Market Report. ...
EU: Tanks, Casks, Drums, Cans, Boxes And Similar Containers - Market Report. ...IndexBox Marketing
 
The Minister's Black Veil - in class notes
The Minister's Black Veil - in class notesThe Minister's Black Veil - in class notes
The Minister's Black Veil - in class noteslramirezcruz
 
Machine Learning Software Design Pattern with PredictionIO
Machine Learning Software Design Pattern with PredictionIOMachine Learning Software Design Pattern with PredictionIO
Machine Learning Software Design Pattern with PredictionIOTuri, Inc.
 
PredictionIO - Building Applications That Predict User Behavior Through Big D...
PredictionIO - Building Applications That Predict User Behavior Through Big D...PredictionIO - Building Applications That Predict User Behavior Through Big D...
PredictionIO - Building Applications That Predict User Behavior Through Big D...predictionio
 
Romania: Equipment For Scaffolding, Shuttering, Propping Or Pit Propping - Ma...
Romania: Equipment For Scaffolding, Shuttering, Propping Or Pit Propping - Ma...Romania: Equipment For Scaffolding, Shuttering, Propping Or Pit Propping - Ma...
Romania: Equipment For Scaffolding, Shuttering, Propping Or Pit Propping - Ma...IndexBox Marketing
 
The Rest Architectural Style
The Rest Architectural StyleThe Rest Architectural Style
The Rest Architectural StyleRobert Wilson
 
Chapter 6 pharmacy calculation
Chapter 6 pharmacy calculationChapter 6 pharmacy calculation
Chapter 6 pharmacy calculationrr0006
 
Dosage Calculation Using Formula Method
Dosage Calculation Using Formula MethodDosage Calculation Using Formula Method
Dosage Calculation Using Formula Methodwindleh
 
Aerosol , components for aerosol formulation by mariomakhter@yahoo.com
Aerosol , components for aerosol formulation by mariomakhter@yahoo.comAerosol , components for aerosol formulation by mariomakhter@yahoo.com
Aerosol , components for aerosol formulation by mariomakhter@yahoo.commariomS7
 

Viewers also liked (16)

Speech Outline Presentation
Speech Outline PresentationSpeech Outline Presentation
Speech Outline Presentation
 
Bruce Power Saver Brochure
Bruce Power Saver BrochureBruce Power Saver Brochure
Bruce Power Saver Brochure
 
ASP.NET AJAX
ASP.NET AJAXASP.NET AJAX
ASP.NET AJAX
 
ACCDocketArticle12_2015
ACCDocketArticle12_2015ACCDocketArticle12_2015
ACCDocketArticle12_2015
 
EU: Tanks, Casks, Drums, Cans, Boxes And Similar Containers - Market Report. ...
EU: Tanks, Casks, Drums, Cans, Boxes And Similar Containers - Market Report. ...EU: Tanks, Casks, Drums, Cans, Boxes And Similar Containers - Market Report. ...
EU: Tanks, Casks, Drums, Cans, Boxes And Similar Containers - Market Report. ...
 
The Minister's Black Veil - in class notes
The Minister's Black Veil - in class notesThe Minister's Black Veil - in class notes
The Minister's Black Veil - in class notes
 
Machine Learning Software Design Pattern with PredictionIO
Machine Learning Software Design Pattern with PredictionIOMachine Learning Software Design Pattern with PredictionIO
Machine Learning Software Design Pattern with PredictionIO
 
PredictionIO - Building Applications That Predict User Behavior Through Big D...
PredictionIO - Building Applications That Predict User Behavior Through Big D...PredictionIO - Building Applications That Predict User Behavior Through Big D...
PredictionIO - Building Applications That Predict User Behavior Through Big D...
 
Romania: Equipment For Scaffolding, Shuttering, Propping Or Pit Propping - Ma...
Romania: Equipment For Scaffolding, Shuttering, Propping Or Pit Propping - Ma...Romania: Equipment For Scaffolding, Shuttering, Propping Or Pit Propping - Ma...
Romania: Equipment For Scaffolding, Shuttering, Propping Or Pit Propping - Ma...
 
Vet tech
Vet techVet tech
Vet tech
 
The Rest Architectural Style
The Rest Architectural StyleThe Rest Architectural Style
The Rest Architectural Style
 
Posham R - AIMRADIAL 2014 Endovascular - Chemoembolization
Posham R - AIMRADIAL 2014 Endovascular - ChemoembolizationPosham R - AIMRADIAL 2014 Endovascular - Chemoembolization
Posham R - AIMRADIAL 2014 Endovascular - Chemoembolization
 
PredictionIO
PredictionIOPredictionIO
PredictionIO
 
Chapter 6 pharmacy calculation
Chapter 6 pharmacy calculationChapter 6 pharmacy calculation
Chapter 6 pharmacy calculation
 
Dosage Calculation Using Formula Method
Dosage Calculation Using Formula MethodDosage Calculation Using Formula Method
Dosage Calculation Using Formula Method
 
Aerosol , components for aerosol formulation by mariomakhter@yahoo.com
Aerosol , components for aerosol formulation by mariomakhter@yahoo.comAerosol , components for aerosol formulation by mariomakhter@yahoo.com
Aerosol , components for aerosol formulation by mariomakhter@yahoo.com
 

Similar to spray: REST on Akka

Scala45 spray test
Scala45 spray testScala45 spray test
Scala45 spray testkopiczko
 
API Days Australia - Automatic Testing of (RESTful) API Documentation
API Days Australia  - Automatic Testing of (RESTful) API DocumentationAPI Days Australia  - Automatic Testing of (RESTful) API Documentation
API Days Australia - Automatic Testing of (RESTful) API DocumentationRouven Weßling
 
JAX-RS JavaOne Hyderabad, India 2011
JAX-RS JavaOne Hyderabad, India 2011JAX-RS JavaOne Hyderabad, India 2011
JAX-RS JavaOne Hyderabad, India 2011Shreedhar Ganapathy
 
API Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API DocumentationAPI Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API DocumentationRouven Weßling
 
Spark IT 2011 - Developing RESTful Web services with JAX-RS
Spark IT 2011 - Developing RESTful Web services with JAX-RSSpark IT 2011 - Developing RESTful Web services with JAX-RS
Spark IT 2011 - Developing RESTful Web services with JAX-RSArun Gupta
 
Nordic APIs - Automatic Testing of (RESTful) API Documentation
Nordic APIs - Automatic Testing of (RESTful) API DocumentationNordic APIs - Automatic Testing of (RESTful) API Documentation
Nordic APIs - Automatic Testing of (RESTful) API DocumentationRouven Weßling
 
Building RESTful applications using Spring MVC
Building RESTful applications using Spring MVCBuilding RESTful applications using Spring MVC
Building RESTful applications using Spring MVCIndicThreads
 
API Testing. Streamline your testing process.
API Testing. Streamline your testing process.API Testing. Streamline your testing process.
API Testing. Streamline your testing process.Andrey Oleynik
 
RESTful Web services using JAX-RS
RESTful Web services using JAX-RSRESTful Web services using JAX-RS
RESTful Web services using JAX-RSArun Gupta
 
ITB2016 - Building ColdFusion RESTFul Services
ITB2016 - Building ColdFusion RESTFul ServicesITB2016 - Building ColdFusion RESTFul Services
ITB2016 - Building ColdFusion RESTFul ServicesOrtus Solutions, Corp
 
Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019Joe Keeley
 
Rest with Java EE 6 , Security , Backbone.js
Rest with Java EE 6 , Security , Backbone.jsRest with Java EE 6 , Security , Backbone.js
Rest with Java EE 6 , Security , Backbone.jsCarol McDonald
 

Similar to spray: REST on Akka (20)

Spray human talks
Spray human talksSpray human talks
Spray human talks
 
Scala45 spray test
Scala45 spray testScala45 spray test
Scala45 spray test
 
Web api
Web apiWeb api
Web api
 
API Days Australia - Automatic Testing of (RESTful) API Documentation
API Days Australia  - Automatic Testing of (RESTful) API DocumentationAPI Days Australia  - Automatic Testing of (RESTful) API Documentation
API Days Australia - Automatic Testing of (RESTful) API Documentation
 
JAX-RS JavaOne Hyderabad, India 2011
JAX-RS JavaOne Hyderabad, India 2011JAX-RS JavaOne Hyderabad, India 2011
JAX-RS JavaOne Hyderabad, India 2011
 
API Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API DocumentationAPI Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API Documentation
 
Spark IT 2011 - Developing RESTful Web services with JAX-RS
Spark IT 2011 - Developing RESTful Web services with JAX-RSSpark IT 2011 - Developing RESTful Web services with JAX-RS
Spark IT 2011 - Developing RESTful Web services with JAX-RS
 
Nordic APIs - Automatic Testing of (RESTful) API Documentation
Nordic APIs - Automatic Testing of (RESTful) API DocumentationNordic APIs - Automatic Testing of (RESTful) API Documentation
Nordic APIs - Automatic Testing of (RESTful) API Documentation
 
scalaphx-akka-http
scalaphx-akka-httpscalaphx-akka-http
scalaphx-akka-http
 
Building RESTful applications using Spring MVC
Building RESTful applications using Spring MVCBuilding RESTful applications using Spring MVC
Building RESTful applications using Spring MVC
 
On being RESTful
On being RESTfulOn being RESTful
On being RESTful
 
Apex REST
Apex RESTApex REST
Apex REST
 
Ws rest
Ws restWs rest
Ws rest
 
API Testing. Streamline your testing process.
API Testing. Streamline your testing process.API Testing. Streamline your testing process.
API Testing. Streamline your testing process.
 
RESTful Web services using JAX-RS
RESTful Web services using JAX-RSRESTful Web services using JAX-RS
RESTful Web services using JAX-RS
 
ITB2016 - Building ColdFusion RESTFul Services
ITB2016 - Building ColdFusion RESTFul ServicesITB2016 - Building ColdFusion RESTFul Services
ITB2016 - Building ColdFusion RESTFul Services
 
Rest with Spring
Rest with SpringRest with Spring
Rest with Spring
 
Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019
 
Rest
RestRest
Rest
 
Rest with Java EE 6 , Security , Backbone.js
Rest with Java EE 6 , Security , Backbone.jsRest with Java EE 6 , Security , Backbone.js
Rest with Java EE 6 , Security , Backbone.js
 

Recently uploaded

WomenInAutomation2024: AI and Automation for eveyone
WomenInAutomation2024: AI and Automation for eveyoneWomenInAutomation2024: AI and Automation for eveyone
WomenInAutomation2024: AI and Automation for eveyoneUiPathCommunity
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkPixlogix Infotech
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesManik S Magar
 
Kuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorialKuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorialJoão Esperancinha
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...BookNet Canada
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Jeffrey Haguewood
 
Deliver Latency Free Customer Experience
Deliver Latency Free Customer ExperienceDeliver Latency Free Customer Experience
Deliver Latency Free Customer ExperienceOpsTree solutions
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxAna-Maria Mihalceanu
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...itnewsafrica
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
Digital Tools & AI in Career Development
Digital Tools & AI in Career DevelopmentDigital Tools & AI in Career Development
Digital Tools & AI in Career DevelopmentMahmoud Rabie
 
Laying the Data Foundations for Artificial Intelligence!
Laying the Data Foundations for Artificial Intelligence!Laying the Data Foundations for Artificial Intelligence!
Laying the Data Foundations for Artificial Intelligence!Memoori
 
Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Karmanjay Verma
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxfnnc6jmgwh
 

Recently uploaded (20)

WomenInAutomation2024: AI and Automation for eveyone
WomenInAutomation2024: AI and Automation for eveyoneWomenInAutomation2024: AI and Automation for eveyone
WomenInAutomation2024: AI and Automation for eveyone
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App Framework
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
 
Kuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorialKuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorial
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
 
Deliver Latency Free Customer Experience
Deliver Latency Free Customer ExperienceDeliver Latency Free Customer Experience
Deliver Latency Free Customer Experience
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance Toolbox
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
Digital Tools & AI in Career Development
Digital Tools & AI in Career DevelopmentDigital Tools & AI in Career Development
Digital Tools & AI in Career Development
 
Laying the Data Foundations for Artificial Intelligence!
Laying the Data Foundations for Artificial Intelligence!Laying the Data Foundations for Artificial Intelligence!
Laying the Data Foundations for Artificial Intelligence!
 
Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
 

spray: REST on Akka

  • 1. REST on Akka ⇗ northeast scala symposium March 9th, 2012
  • 3. What is spray? Suite of libraries for building and consuming RESTful web services on top of Akka
  • 4. What is spray? Suite of libraries for building and consuming RESTful web services on top of Akka • First released about 1 year ago
  • 5. What is spray? Suite of libraries for building and consuming RESTful web services on top of Akka • First released about 1 year ago • Principles: lightweight, async, non-blocking, actor-based, modular, few deps, testable
  • 6. What is spray? Suite of libraries for building and consuming RESTful web services on top of Akka • First released about 1 year ago • Principles: lightweight, async, non-blocking, actor-based, modular, few deps, testable • Philosophy: library, not framework
  • 9. Components • Rich immutable HTTP model • spray-server: DSL for server-side API construction
  • 10. Components • Rich immutable HTTP model • spray-server: DSL for server-side API construction • spray-client: complementary HTTP client
  • 11. 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
  • 12. 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)
  • 14. spray-server • Runs on servlet containers or spray-can
  • 15. spray-server • Runs on servlet containers or spray-can • Tool for building a “self-contained” API layer
  • 16. 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
  • 17. 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
  • 18. Basic Architecture Application Business Logic
  • 19. Basic Architecture REST API layer Application Routing Logic Business Logic
  • 20. Basic Architecture REST API layer Application HTTP Request Routing Logic Business Logic
  • 21. Basic Architecture REST API layer Application HTTP Request Action Routing Logic Business Logic
  • 22. Basic Architecture REST API layer Application HTTP Request Action domain Routing object ! Business Logic Logic
  • 23. Basic Architecture REST API layer Application HTTP Request Action domain Routing object ! Business Logic Logic Reply
  • 24. Basic Architecture REST API layer Application HTTP Request Action domain Routing object ! Business Logic Logic Reply
  • 25. Basic Architecture REST API layer Application HTTP Request Action domain Routing object ! Business Logic Logic HTTP Response Reply
  • 27. API Layer Responsibilities • Request routing based on method, path, query parameters, entity
  • 28. API Layer Responsibilities • Request routing based on method, path, query parameters, entity • (Un)marshalling to / from domain objects
  • 29. API Layer Responsibilities • Request routing based on method, path, query parameters, entity • (Un)marshalling to / from domain objects • Encoding / decoding
  • 30. API Layer Responsibilities • Request routing based on method, path, query parameters, entity • (Un)marshalling to / from domain objects • Encoding / decoding • Authentication / authorization
  • 31. 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
  • 32. 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
  • 33. 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 } } }
  • 34. Routing Basics Routes in spray: type Route = RequestContext => Unit
  • 35. Routing Basics Routes in spray: type Route = RequestContext => Unit Explicit continuation- passing style
  • 36. Routing Basics Routes in spray: type Route = RequestContext => Unit Explicit continuation- passing style Central object: case class RequestContext( request: HttpRequest, ...) {   def complete(...) { ... }   def reject(...) { ... }   ... }
  • 37. Routing Basics The simplest route: ctx => ctx.complete("Say hello to spray")
  • 38. Routing Basics The simplest route: ctx => ctx.complete("Say hello to spray") or: _.complete("Say hello to spray")
  • 39. 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")
  • 40. 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)
  • 41. 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 } } }
  • 42. Directives Route structure built with directives: val route: Route = path("order" / HexIntNumber) { id => get { completeWith { "Received GET request for order " + id } directive }~ name put { completeWith { "Received PUT request for order " + id } } }
  • 43. Directives Route structure built with directives: val route: Route = path("order" / HexIntNumber) { id => get { completeWith { "Received GET request for order " + id } }~ args put { completeWith { "Received PUT request for order " + id } } }
  • 44. Directives Route structure built with directives: val route: Route = path("order" / HexIntNumber) { id => get { extractions completeWith { "Received GET request for order " + id } }~ put { completeWith { "Received PUT request for order " + id } } }
  • 45. 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 } } inner route }
  • 46. Directives Route structure built with directives: val route: Route = path("order" / HexIntNumber) { id => get { completeWith { "Received GET request for order " + id }~ } route concatenation: put { recover from rejections completeWith { "Received PUT request for order " + id } } }
  • 47. 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 } } }
  • 48. 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 } } Route structure } forms a tree!
  • 49. Directives DRYing up with the `|` operator: val route = path("order" / HexIntNumber) { id => (get | put) { ctx => ctx.complete("Received " + ctx.request.method + " request for order " + id) } }
  • 50. Directives Pulling out a custom directive: val getOrPut = get | put val route = path("order" / HexIntNumber) { id => getOrPut { ctx => ctx.complete("Received " + ctx.request.method + " request for order " + id) } }
  • 51. Directives The `&` operator as alternative to nesting: val getOrPut = get | put val route = (path("order" / HexIntNumber) & getOrPut) { id => ctx => ctx.complete("Received " + ctx.request.method + " request for order " + id) }
  • 52. Directives Pulling out once more: val orderGetOrPut = path("order" / HexIntNumber) & (get | put) val route = orderGetOrPut { id => ctx => ctx.complete("Received " + ctx.request.method + " request for order " + id) }
  • 53. Directives Operators are type-safe: val orderPath = path("order" / IntNumber)
  • 54. Directives Compiles? Operators are type-safe: val orderPath = path("order" / IntNumber)
  • 55. Directives Compiles? Operators are type-safe: val orderPath = path("order" / IntNumber) val dir = orderPath | get
  • 56. Directives Compiles? Operators are type-safe: val orderPath = path("order" / IntNumber) val dir = orderPath | get
  • 57. Directives Compiles? Operators are type-safe: val orderPath = path("order" / IntNumber) val dir = orderPath | get val dir = orderPath | path("[^/]+".r / DoubleNumber)
  • 58. Directives Compiles? Operators are type-safe: val orderPath = path("order" / IntNumber) val dir = orderPath | get val dir = orderPath | path("[^/]+".r / DoubleNumber)
  • 59. 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])
  • 60. 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])
  • 61. 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 ?)
  • 62. 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 ?)
  • 63. 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 }
  • 64. Directives spray 0.9.0 comes with 69 predefined directives: alwaysPass, authenticate, authorize, autoChunk, cache, cacheResults, clientIP, completeWith, content, cookie, decodeRequest, delete, deleteCookie, detach, dynamic, encodeResponse, filter, filter1, filter2, filter3, filter4, filter5, filter6, filter7, filter8, filter9, formField, formFields, get, getFromDirectory, getFromFile, getFromFileName, getFromResource, getFromResourceDirectory, handleWith, hardFail, head, headerValue, headerValuePF, host, jsonpWithParameter, method, optionalCookie, options, parameter, parameters, path, pathPrefix, post, produce, provide, put, redirect, reject, respondWithContentType, respondWithHeader, respondWithHeaders, respondWithMediaType, respondWithStatus, setCookie, trace, transformChunkedResponse, transformRejections, transformRequest, transformRequestContext, transformResponse, transformRoute, transformUnchunkedResponse, validate
  • 65. 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,
  • 66. } } }~ } } Real World Example tokenAuthenticate { user => path("ranking") { get { countAndTime(user, "ranking") { parameters('fixed ? 0, 'mobile ? 0, 'sms ? 0, 'mms ? 0, 'data ? 0).as(RankingDescriptor) { descr => (rankingService ? Ranking(descr)).mapTo[RankingResult] } } } }~ path("accounts") { post { authorize(user.isAdmin) { content(as[AccountDetails]) { details => (accountService ? NewAccount(details)).mapTo[OpResult] } } } }~ path("account" / IntNumber) { accountId => get { ... } ~ put { ... } ~ delete { ... } } } }~ pathPrefix("v1") {
  • 67. } }~ Real World Example path("account" / IntNumber) { accountId => get { ... } ~ put { ... } ~ delete { ... } } } }~ pathPrefix("v1") { proxyToDjango } }~ pathPrefix("doc") { respondWithHeader(`Cache-Control`(`max-age`(3600))) { transformResponse(_.withContentTransformed(markdown2Html)) { getFromResourceDirectory("doc/root", pathRewriter = appendFileExt) } } }~ }~ cacheIfEnabled { encodeResponse(Gzip) { getFromResourceDirectory("public") } } }
  • 69. Best Practices • Keep route structure clean and readable, pull out all logic into custom directives
  • 70. Best Practices • Keep route structure clean and readable, pull out all logic into custom directives • Don’t let API layer leak into application
  • 71. 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
  • 72. 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`
  • 73. 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 turn- around
  • 75. There is more ... • SprayJsonSupport, LiftJsonSupport, TwirlSupport, ScalateSupport
  • 76. There is more ... • SprayJsonSupport, LiftJsonSupport, TwirlSupport, ScalateSupport • Asynchronous response push streaming
  • 77. There is more ... • SprayJsonSupport, LiftJsonSupport, TwirlSupport, ScalateSupport • Asynchronous response push streaming • Testing spray routes
  • 78. There is more ... • SprayJsonSupport, LiftJsonSupport, TwirlSupport, ScalateSupport • Asynchronous response push streaming • Testing spray routes • RESTful errors
  • 79. There is more ... • SprayJsonSupport, LiftJsonSupport, TwirlSupport, ScalateSupport • Asynchronous response push streaming • Testing spray routes • RESTful errors • spray-client
  • 81. Current State • spray 0.9.0 just released (last release for Akka 1.x)
  • 82. Current State • spray 0.9.0 just released (last release for Akka 1.x) • Current focus: Release first Akka 2.0 compatible milestone of spray 1.0
  • 83. Current State • spray 0.9.0 just released (last release for Akka 1.x) • Current focus: Release first Akka 2.0 compatible milestone of spray 1.0 • Coming features: new documentation site, deeper REST support, monitoring, request throttling, and more ...
  • 84. A few current sprayers ...
  • 85. Getting started • Main site & documentation: https://github.com/spray/spray/wiki • Mailing list: http://groups.google.com/group/spray-user • Twitter: @spraycc
  • 87. More
  • 88. Proxying with spray Combining with spray-client to build a proxy: val conduit = new HttpConduit("target.example.com", 8080) lazy val proxyToTarget: Route = { ctx => ctx.complete { conduit.sendReceive { ctx.request.withHeadersTransformed { _.filter(_.name != "Host") } }.map { _.withHeadersTransformed { _.filter(_.name != "Date") } } }

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n