SlideShare a Scribd company logo
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 Preso
Dan Yoder
 
Onion Architecture and the Blog
Onion Architecture and the BlogOnion Architecture and the Blog
Onion Architecture and the Blog
barryosull
 
Kafka Needs No Keeper
Kafka Needs No KeeperKafka Needs No Keeper
Kafka Needs No Keeper
C4Media
 
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 APIs
Cisco DevNet
 
Rest APIs Training
Rest APIs TrainingRest APIs Training
Rest APIs Training
Shekhar Kumar
 
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-slides
Cisco DevNet
 
Ruby Under The Hood
Ruby Under The HoodRuby Under The Hood
Ruby Under The Hood
craig lehmann
 
05 integrate redis
05 integrate redis05 integrate redis
05 integrate redis
Erhwen Kuo
 
Above the clouds: introducing Akka
Above the clouds: introducing AkkaAbove the clouds: introducing Akka
Above the clouds: introducing Akka
nartamonov
 
Fault Tolerance in Distributed Environment
Fault Tolerance in Distributed EnvironmentFault Tolerance in Distributed Environment
Fault Tolerance in Distributed Environment
Orkhan Gasimov
 
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
AzRy LLC, Caucasus School of Technology
 
Java APIs - the missing manual
Java APIs - the missing manualJava APIs - the missing manual
Java APIs - the missing manual
Hendrik Ebbers
 
Akka Actor presentation
Akka Actor presentationAkka Actor presentation
Akka Actor presentation
Gene 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 NGSIv1
FIWARE
 
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
Databricks
 
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
Ashish 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 Spark
Jen 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

Speech Outline Presentation
Speech Outline PresentationSpeech Outline Presentation
Speech Outline Presentation
Jodie-Ann Mullings
 
Bruce Power Saver Brochure
Bruce Power Saver BrochureBruce Power Saver Brochure
Bruce Power Saver BrochureSteve Glover
 
ASP.NET AJAX
ASP.NET AJAXASP.NET AJAX
ASP.NET AJAX
Nelson Correia
 
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 PredictionIO
Turi, 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
 
Vet tech
Vet techVet tech
Vet tech
stanbridge
 
The Rest Architectural Style
The Rest Architectural StyleThe Rest Architectural Style
The Rest Architectural Style
Robert Wilson
 
Posham R - AIMRADIAL 2014 Endovascular - Chemoembolization
Posham R - AIMRADIAL 2014 Endovascular - ChemoembolizationPosham R - AIMRADIAL 2014 Endovascular - Chemoembolization
Posham R - AIMRADIAL 2014 Endovascular - Chemoembolization
International Chair on Interventional Cardiology and Transradial Approach
 
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.com
mariomS7
 

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

Spray human talks
Spray human talksSpray human talks
Spray human talks
antoinecomte
 
Scala45 spray test
Scala45 spray testScala45 spray test
Scala45 spray test
kopiczko
 
Web api
Web apiWeb 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
Rouven 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 Documentation
Rouven 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-RS
Arun 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 Documentation
Rouven Weßling
 
Building RESTful applications using Spring MVC
Building RESTful applications using Spring MVCBuilding RESTful applications using Spring MVC
Building RESTful applications using Spring MVC
IndicThreads
 
Apex REST
Apex RESTApex REST
Apex REST
Boris Bachovski
 
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-RS
Arun Gupta
 
ITB2016 - Building ColdFusion RESTFul Services
ITB2016 - Building ColdFusion RESTFul ServicesITB2016 - Building ColdFusion RESTFul Services
ITB2016 - Building ColdFusion RESTFul Services
Ortus Solutions, Corp
 
Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019
Joe 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 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
 
Rest
RestRest
Rest
 

Recently uploaded

LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
Quantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIsQuantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIs
Vlad Stirbu
 
Enhancing Performance with Globus and the Science DMZ
Enhancing Performance with Globus and the Science DMZEnhancing Performance with Globus and the Science DMZ
Enhancing Performance with Globus and the Science DMZ
Globus
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
DianaGray10
 
Free Complete Python - A step towards Data Science
Free Complete Python - A step towards Data ScienceFree Complete Python - A step towards Data Science
Free Complete Python - A step towards Data Science
RinaMondal9
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex ProofszkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
Alex Pruden
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptxSecstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
nkrafacyberclub
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
Alpen-Adria-Universität
 
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
UiPathCommunity
 
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfSAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
Peter Spielvogel
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
UiPath Community Day Dubai: AI at Work..
UiPath Community Day Dubai: AI at Work..UiPath Community Day Dubai: AI at Work..
UiPath Community Day Dubai: AI at Work..
UiPathCommunity
 

Recently uploaded (20)

LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
Quantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIsQuantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIs
 
Enhancing Performance with Globus and the Science DMZ
Enhancing Performance with Globus and the Science DMZEnhancing Performance with Globus and the Science DMZ
Enhancing Performance with Globus and the Science DMZ
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
 
Free Complete Python - A step towards Data Science
Free Complete Python - A step towards Data ScienceFree Complete Python - A step towards Data Science
Free Complete Python - A step towards Data Science
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex ProofszkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptxSecstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
 
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
 
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfSAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
UiPath Community Day Dubai: AI at Work..
UiPath Community Day Dubai: AI at Work..UiPath Community Day Dubai: AI at Work..
UiPath Community Day Dubai: AI at Work..
 

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