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

"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 

Recently uploaded (20)

"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 

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