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

Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 

Recently uploaded (20)

Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 

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