SlideShare une entreprise Scribd logo
1  sur  111
REST on Akka
  Scala Days
April 17th, 2012
What is spray?
What is spray?
Vision: Provide the best toolkit for REST/HTTP
and low-level network-IO on top of Akka
What is spray?
Vision: Provide the best toolkit for REST/HTTP
and low-level network-IO on top of Akka
• First released about 1 year ago
What is spray?
Vision: Provide the best toolkit for REST/HTTP
and low-level network-IO on top of Akka
• First released about 1 year ago
• Principles: lightweight, async, non-blocking,
  actor-based, modular, few deps, testable
What is spray?
Vision: Provide the best toolkit for REST/HTTP
and low-level network-IO on top of Akka
• First released about 1 year ago
• Principles: lightweight, async, non-blocking,
  actor-based, modular, few deps, testable
• Philosophy: set of libraries, not framework
Current State
Current State
Transitioning from Akka 1.3 to Akka 2.0
Current State
Transitioning from Akka 1.3 to Akka 2.0
• spray 0.9.0 for Akka 1.3 released in March
Current State
Transitioning from Akka 1.3 to Akka 2.0
• spray 0.9.0 for Akka 1.3 released in March
• spray 1.0-M1 for Akka 2.0 two weeks ago
Current State
Transitioning from Akka 1.3 to Akka 2.0
• spray 0.9.0 for Akka 1.3 released in March
• spray 1.0-M1 for Akka 2.0 two weeks ago
• Next: second milestone of spray 1.0
Current State
Transitioning from Akka 1.3 to Akka 2.0
• spray 0.9.0 for Akka 1.3 released in March
• spray 1.0-M1 for Akka 2.0 two weeks ago
• Next: second milestone of spray 1.0
                       Focus of this talk
Components
spray-routing    spray-client



spray-servlet     spray-can     spray-json



 spray-http       spray-io
Components
spray-routing        spray-client



spray-servlet         spray-can          spray-json



 spray-http           spray-io
                Low-level, “actorized”
                    network IO
Components
    spray-routing     spray-client



    spray-servlet      spray-can     spray-json



     spray-http        spray-io
rich immutable HTTP
   model (no Akka)
Components
spray-routing      spray-client



spray-servlet       spray-can       spray-json
                 low-level HTTP
                server and client
 spray-http          spray-io
Components
 spray-routing    spray-client



 spray-servlet     spray-can     spray-json
 Servlet API
adapter layer
  spray-http       spray-io
Components
   spray-routing      spray-client
DSL for server-side
 API construction
    spray-servlet      spray-can     spray-json



     spray-http        spray-io
Components
spray-routing        spray-client
                Complementary high-
                  level HTTP client
spray-servlet         spray-can       spray-json



 spray-http           spray-io
Components
spray-routing    spray-client



spray-servlet     spray-can        spray-json
                                straight JSON in
                                Scala (no Akka)
 spray-http       spray-io
Components
 spray-routing     spray-client
 Focus for the
rest of the talk
 spray-servlet      spray-can     spray-json



   spray-http       spray-io
spray-routing
spray-routing
• Runs on spray-servlet or spray-can
spray-routing
• Runs on spray-servlet or spray-can
• Tool for building a “self-contained” API layer
spray-routing
• Runs on spray-servlet or spray-can
• Tool for building a “self-contained” API layer
• Central element:
  Routing DSL for defining web API behavior
spray-routing
• Runs on spray-servlet 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 (compression)
API Layer Responsibilities
• Request routing based on method, path,
  query parameters, entity
• (Un)marshalling to / from domain objects
• Encoding / decoding (compression)
• Authentication / authorization
API Layer Responsibilities
• Request routing based on method, path,
  query parameters, entity
• (Un)marshalling to / from domain objects
• Encoding / decoding (compression)
• 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 (compression)
• Authentication / authorization
• Caching and serving static content
• RESTful error handling
API Building in spray
API Building in spray
• HTTP messages are actor messages
API Building in spray
• HTTP messages are actor messages
  class PingServiceActor extends Actor {
    def receive = {
      case HttpRequest(GET, "/ping", _, _, _) =>
        sender ! HttpResponse(200, "PONG")
    }
  }
API Building in spray
• HTTP messages are actor messages
  class PingServiceActor extends Actor {
    def receive = {
      case HttpRequest(GET, "/ping", _, _, _) =>
        sender ! HttpResponse(200, "PONG")
    }
  }



• Could build services only via pattern-matching
API Building in spray
• HTTP messages are actor messages
  class PingServiceActor extends Actor {
    def receive = {
      case HttpRequest(GET, "/ping", _, _, _) =>
        sender ! HttpResponse(200, "PONG")
    }
  }



• Could build services only via pattern-matching
• But: pattern-matching becomes awkward for
  more complex service definitions
API Building in spray: DSL
Simple example:
class MyServiceActor extends Actor with Routing {
  def receive = receiveFromRoute {
    path("order" / HexIntNumber) { id =>
      get {
        completeWith {
          "Received GET request for order " + id
        }
      } ~
      put {
        completeWith {
          "Received PUT request for order " + id
        }
      }
    }
  }
}
sprays Routing DSL
sprays Routing DSL
• Built from recombinant elements called
  “directives”
sprays Routing DSL
• Built from recombinant elements called
  “directives”
• Concise, readable, maintainable
sprays Routing DSL
• Built from recombinant elements called
  “directives”
• Concise, readable, maintainable
• Highly composable
sprays Routing DSL
• Built from recombinant elements called
  “directives”
• Concise, readable, maintainable
• Highly composable
• Type-safe
sprays Routing DSL
• Built from recombinant elements called
  “directives”
• Concise, readable, maintainable
• Highly composable
• Type-safe
• Easily extensible with custom constructs
sprays Routing DSL
• Built from recombinant elements called
  “directives”
• Concise, readable, maintainable
• Highly composable
• Type-safe
• Easily extensible with custom constructs
• Directly interfaces with Akka API
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
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
• 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
There is more ...
• SprayJsonSupport, LiftJsonSupport,
  TwirlSupport, ScalateSupport
• Asynchronous response push streaming
• Testing spray routes
• RESTful errors
• spray-client
• spray-io
What’s next?
What’s next?
• release 1.0 featuring improved and simplified
  API for Akka 2.0
What’s next?
• release 1.0 featuring improved and simplified
  API for Akka 2.0
• Better and deeper documentation
  (follow Akkas model of treating docs as code)
What’s next?
• release 1.0 featuring improved and simplified
  API for Akka 2.0
• Better and deeper documentation
  (follow Akkas model of treating docs as code)
• Coming features: deeper REST support,
  monitoring, request throttling, ...
What’s next?
• release 1.0 featuring improved and simplified
  API for Akka 2.0
• Better and deeper documentation
  (follow Akkas model of treating docs as code)
• Coming features: deeper REST support,
  monitoring, request throttling, ...
• Possibly: websockets, SPDY
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
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
     }
   }
 }
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
}
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")
      }
    }
  }

Contenu connexe

Tendances

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
 
Streaming Microservices With Akka Streams And Kafka Streams
Streaming Microservices With Akka Streams And Kafka StreamsStreaming Microservices With Akka Streams And Kafka Streams
Streaming Microservices With Akka Streams And Kafka StreamsLightbend
 
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
 
Spark Job Server and Spark as a Query Engine (Spark Meetup 5/14)
Spark Job Server and Spark as a Query Engine (Spark Meetup 5/14)Spark Job Server and Spark as a Query Engine (Spark Meetup 5/14)
Spark Job Server and Spark as a Query Engine (Spark Meetup 5/14)Evan Chan
 
Akka Streams and HTTP
Akka Streams and HTTPAkka Streams and HTTP
Akka Streams and HTTPRoland Kuhn
 
Above the clouds: introducing Akka
Above the clouds: introducing AkkaAbove the clouds: introducing Akka
Above the clouds: introducing Akkanartamonov
 
Akka-chan's Survival Guide for the Streaming World
Akka-chan's Survival Guide for the Streaming WorldAkka-chan's Survival Guide for the Streaming World
Akka-chan's Survival Guide for the Streaming WorldKonrad Malawski
 
Revitalizing Enterprise Integration with Reactive Streams
Revitalizing Enterprise Integration with Reactive StreamsRevitalizing Enterprise Integration with Reactive Streams
Revitalizing Enterprise Integration with Reactive StreamsLightbend
 
Apache Con 2021 : Apache Bookkeeper Key Value Store and use cases
Apache Con 2021 : Apache Bookkeeper Key Value Store and use casesApache Con 2021 : Apache Bookkeeper Key Value Store and use cases
Apache Con 2021 : Apache Bookkeeper Key Value Store and use casesShivji Kumar Jha
 
Show Me Kafka Tools That Will Increase My Productivity! (Stephane Maarek, Dat...
Show Me Kafka Tools That Will Increase My Productivity! (Stephane Maarek, Dat...Show Me Kafka Tools That Will Increase My Productivity! (Stephane Maarek, Dat...
Show Me Kafka Tools That Will Increase My Productivity! (Stephane Maarek, Dat...confluent
 
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
 
Concurrency in Scala - the Akka way
Concurrency in Scala - the Akka wayConcurrency in Scala - the Akka way
Concurrency in Scala - the Akka wayYardena Meymann
 
Spark Streaming & Kafka-The Future of Stream Processing
Spark Streaming & Kafka-The Future of Stream ProcessingSpark Streaming & Kafka-The Future of Stream Processing
Spark Streaming & Kafka-The Future of Stream ProcessingJack Gudenkauf
 
LA Ember.js Meetup, Jan 2017
LA Ember.js Meetup, Jan 2017LA Ember.js Meetup, Jan 2017
LA Ember.js Meetup, Jan 2017Matthew Beale
 
Transaction preview of Apache Pulsar
Transaction preview of Apache PulsarTransaction preview of Apache Pulsar
Transaction preview of Apache PulsarStreamNative
 
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.
 
orioncontextbroker-ngsiv2-overview-for-developers-that-already-know-ngsiv1-20...
orioncontextbroker-ngsiv2-overview-for-developers-that-already-know-ngsiv1-20...orioncontextbroker-ngsiv2-overview-for-developers-that-already-know-ngsiv1-20...
orioncontextbroker-ngsiv2-overview-for-developers-that-already-know-ngsiv1-20...Fermin Galan
 
VJUG24 - Reactive Integrations with Akka Streams
VJUG24  - Reactive Integrations with Akka StreamsVJUG24  - Reactive Integrations with Akka Streams
VJUG24 - Reactive Integrations with Akka StreamsJohan Andrén
 

Tendances (20)

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...
 
Streaming Microservices With Akka Streams And Kafka Streams
Streaming Microservices With Akka Streams And Kafka StreamsStreaming Microservices With Akka Streams And Kafka Streams
Streaming Microservices With Akka Streams And Kafka Streams
 
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
 
Akka http
Akka httpAkka http
Akka http
 
Spark Job Server and Spark as a Query Engine (Spark Meetup 5/14)
Spark Job Server and Spark as a Query Engine (Spark Meetup 5/14)Spark Job Server and Spark as a Query Engine (Spark Meetup 5/14)
Spark Job Server and Spark as a Query Engine (Spark Meetup 5/14)
 
Akka Streams and HTTP
Akka Streams and HTTPAkka Streams and HTTP
Akka Streams and HTTP
 
Above the clouds: introducing Akka
Above the clouds: introducing AkkaAbove the clouds: introducing Akka
Above the clouds: introducing Akka
 
Akka-chan's Survival Guide for the Streaming World
Akka-chan's Survival Guide for the Streaming WorldAkka-chan's Survival Guide for the Streaming World
Akka-chan's Survival Guide for the Streaming World
 
Spark+flume seattle
Spark+flume seattleSpark+flume seattle
Spark+flume seattle
 
Revitalizing Enterprise Integration with Reactive Streams
Revitalizing Enterprise Integration with Reactive StreamsRevitalizing Enterprise Integration with Reactive Streams
Revitalizing Enterprise Integration with Reactive Streams
 
Apache Con 2021 : Apache Bookkeeper Key Value Store and use cases
Apache Con 2021 : Apache Bookkeeper Key Value Store and use casesApache Con 2021 : Apache Bookkeeper Key Value Store and use cases
Apache Con 2021 : Apache Bookkeeper Key Value Store and use cases
 
Show Me Kafka Tools That Will Increase My Productivity! (Stephane Maarek, Dat...
Show Me Kafka Tools That Will Increase My Productivity! (Stephane Maarek, Dat...Show Me Kafka Tools That Will Increase My Productivity! (Stephane Maarek, Dat...
Show Me Kafka Tools That Will Increase My Productivity! (Stephane Maarek, Dat...
 
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
 
Concurrency in Scala - the Akka way
Concurrency in Scala - the Akka wayConcurrency in Scala - the Akka way
Concurrency in Scala - the Akka way
 
Spark Streaming & Kafka-The Future of Stream Processing
Spark Streaming & Kafka-The Future of Stream ProcessingSpark Streaming & Kafka-The Future of Stream Processing
Spark Streaming & Kafka-The Future of Stream Processing
 
LA Ember.js Meetup, Jan 2017
LA Ember.js Meetup, Jan 2017LA Ember.js Meetup, Jan 2017
LA Ember.js Meetup, Jan 2017
 
Transaction preview of Apache Pulsar
Transaction preview of Apache PulsarTransaction preview of Apache Pulsar
Transaction preview of Apache Pulsar
 
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
 
orioncontextbroker-ngsiv2-overview-for-developers-that-already-know-ngsiv1-20...
orioncontextbroker-ngsiv2-overview-for-developers-that-already-know-ngsiv1-20...orioncontextbroker-ngsiv2-overview-for-developers-that-already-know-ngsiv1-20...
orioncontextbroker-ngsiv2-overview-for-developers-that-already-know-ngsiv1-20...
 
VJUG24 - Reactive Integrations with Akka Streams
VJUG24  - Reactive Integrations with Akka StreamsVJUG24  - Reactive Integrations with Akka Streams
VJUG24 - Reactive Integrations with Akka Streams
 

En vedette

Medroxyprogesterone Acetate in Glial Tumor Treatment. Our Experimental Results
Medroxyprogesterone Acetate in Glial Tumor Treatment. Our Experimental Results Medroxyprogesterone Acetate in Glial Tumor Treatment. Our Experimental Results
Medroxyprogesterone Acetate in Glial Tumor Treatment. Our Experimental Results NeuroAcademy
 
Scala + Akka + ning/async-http-client - Vancouver Scala meetup February 2015
Scala + Akka + ning/async-http-client - Vancouver Scala meetup February 2015Scala + Akka + ning/async-http-client - Vancouver Scala meetup February 2015
Scala + Akka + ning/async-http-client - Vancouver Scala meetup February 2015Yanik Berube
 
Designing & Implementing Hypermedia APIs – Mike Amundsen, Principal API Archi...
Designing & Implementing Hypermedia APIs – Mike Amundsen, Principal API Archi...Designing & Implementing Hypermedia APIs – Mike Amundsen, Principal API Archi...
Designing & Implementing Hypermedia APIs – Mike Amundsen, Principal API Archi...CA API Management
 
Codemotion akka persistence, cqrs%2 fes y otras siglas del montón
Codemotion   akka persistence, cqrs%2 fes y otras siglas del montónCodemotion   akka persistence, cqrs%2 fes y otras siglas del montón
Codemotion akka persistence, cqrs%2 fes y otras siglas del montónJavier Santos Paniego
 
Akka persistence webinar
Akka persistence webinarAkka persistence webinar
Akka persistence webinarpatriknw
 
Microservices, Monoliths, SOA and How We Got Here
Microservices, Monoliths, SOA and How We Got HereMicroservices, Monoliths, SOA and How We Got Here
Microservices, Monoliths, SOA and How We Got HereLightbend
 
Akka Persistence | Event Sourcing
Akka Persistence | Event SourcingAkka Persistence | Event Sourcing
Akka Persistence | Event SourcingKnoldus Inc.
 
Reactive programming with scala and akka
Reactive programming with scala and akkaReactive programming with scala and akka
Reactive programming with scala and akkaKnoldus Inc.
 
PRIMEROS AUXILIOS
PRIMEROS AUXILIOSPRIMEROS AUXILIOS
PRIMEROS AUXILIOSelbamarina
 
Event Sourcing using Akka on AWS
Event Sourcing using Akka on AWSEvent Sourcing using Akka on AWS
Event Sourcing using Akka on AWSDaniel Pfeiffer
 

En vedette (20)

SOA on Steroids
SOA on SteroidsSOA on Steroids
SOA on Steroids
 
Zen of Akka
Zen of AkkaZen of Akka
Zen of Akka
 
Medroxyprogesterone Acetate in Glial Tumor Treatment. Our Experimental Results
Medroxyprogesterone Acetate in Glial Tumor Treatment. Our Experimental Results Medroxyprogesterone Acetate in Glial Tumor Treatment. Our Experimental Results
Medroxyprogesterone Acetate in Glial Tumor Treatment. Our Experimental Results
 
Modelo acreditacion
Modelo acreditacionModelo acreditacion
Modelo acreditacion
 
Puskesmas
PuskesmasPuskesmas
Puskesmas
 
Horno AEG BE3013521M
Horno AEG BE3013521MHorno AEG BE3013521M
Horno AEG BE3013521M
 
Mónica sánchez
Mónica sánchezMónica sánchez
Mónica sánchez
 
CIOB
CIOBCIOB
CIOB
 
Lavavajillas Aeg F55512M0
Lavavajillas Aeg F55512M0Lavavajillas Aeg F55512M0
Lavavajillas Aeg F55512M0
 
scalaphx-akka-http
scalaphx-akka-httpscalaphx-akka-http
scalaphx-akka-http
 
Scala + Akka + ning/async-http-client - Vancouver Scala meetup February 2015
Scala + Akka + ning/async-http-client - Vancouver Scala meetup February 2015Scala + Akka + ning/async-http-client - Vancouver Scala meetup February 2015
Scala + Akka + ning/async-http-client - Vancouver Scala meetup February 2015
 
Designing & Implementing Hypermedia APIs – Mike Amundsen, Principal API Archi...
Designing & Implementing Hypermedia APIs – Mike Amundsen, Principal API Archi...Designing & Implementing Hypermedia APIs – Mike Amundsen, Principal API Archi...
Designing & Implementing Hypermedia APIs – Mike Amundsen, Principal API Archi...
 
Codemotion akka persistence, cqrs%2 fes y otras siglas del montón
Codemotion   akka persistence, cqrs%2 fes y otras siglas del montónCodemotion   akka persistence, cqrs%2 fes y otras siglas del montón
Codemotion akka persistence, cqrs%2 fes y otras siglas del montón
 
Akka persistence webinar
Akka persistence webinarAkka persistence webinar
Akka persistence webinar
 
Microservices, Monoliths, SOA and How We Got Here
Microservices, Monoliths, SOA and How We Got HereMicroservices, Monoliths, SOA and How We Got Here
Microservices, Monoliths, SOA and How We Got Here
 
Akka Persistence | Event Sourcing
Akka Persistence | Event SourcingAkka Persistence | Event Sourcing
Akka Persistence | Event Sourcing
 
Reactive programming with scala and akka
Reactive programming with scala and akkaReactive programming with scala and akka
Reactive programming with scala and akka
 
PRIMEROS AUXILIOS
PRIMEROS AUXILIOSPRIMEROS AUXILIOS
PRIMEROS AUXILIOS
 
Akka Streams
Akka StreamsAkka Streams
Akka Streams
 
Event Sourcing using Akka on AWS
Event Sourcing using Akka on AWSEvent Sourcing using Akka on AWS
Event Sourcing using Akka on AWS
 

Similaire à spray: REST on Akka (Scala Days)

APIdays San Francisco, 06/22/2013
APIdays San Francisco, 06/22/2013APIdays San Francisco, 06/22/2013
APIdays San Francisco, 06/22/2013Jerome Louvel
 
From Web APIs to Cross-Device Web Sites
From Web APIs to Cross-Device Web SitesFrom Web APIs to Cross-Device Web Sites
From Web APIs to Cross-Device Web SitesRestlet
 
SharePoint Data Anywhere and Everywhere by Chris Beckett - SPTechCon
SharePoint Data Anywhere and Everywhere by Chris Beckett - SPTechConSharePoint Data Anywhere and Everywhere by Chris Beckett - SPTechCon
SharePoint Data Anywhere and Everywhere by Chris Beckett - SPTechConSPTechCon
 
REST-API introduction for developers
REST-API introduction for developersREST-API introduction for developers
REST-API introduction for developersPatrick Savalle
 
Advanced Web Development in PHP - Understanding REST API
Advanced Web Development in PHP - Understanding REST APIAdvanced Web Development in PHP - Understanding REST API
Advanced Web Development in PHP - Understanding REST APIRasan Samarasinghe
 
Ibm_interconnect_restapi_workshop
Ibm_interconnect_restapi_workshopIbm_interconnect_restapi_workshop
Ibm_interconnect_restapi_workshopShubhra Kar
 
Ruby Conf Preso
Ruby Conf PresoRuby Conf Preso
Ruby Conf PresoDan Yoder
 
REST - What's It All About? (SAP TechEd 2012, CD110)
REST - What's It All About? (SAP TechEd 2012, CD110)REST - What's It All About? (SAP TechEd 2012, CD110)
REST - What's It All About? (SAP TechEd 2012, CD110)Sascha Wenninger
 
Birds Eye View on API Development - v1.0
Birds Eye View on API Development - v1.0Birds Eye View on API Development - v1.0
Birds Eye View on API Development - v1.0API Talent
 
Seattle StrongLoop Node.js Workshop
Seattle StrongLoop Node.js WorkshopSeattle StrongLoop Node.js Workshop
Seattle StrongLoop Node.js WorkshopJimmy Guerrero
 
automated-automation-of-rest-apis.pptx
automated-automation-of-rest-apis.pptxautomated-automation-of-rest-apis.pptx
automated-automation-of-rest-apis.pptxAditya274010
 
Mike Taulty MIX10 Silverlight 4 Patterns Frameworks
Mike Taulty MIX10 Silverlight 4 Patterns FrameworksMike Taulty MIX10 Silverlight 4 Patterns Frameworks
Mike Taulty MIX10 Silverlight 4 Patterns Frameworksukdpe
 
Getting Started with the Node.js LoopBack APi Framework
Getting Started with the Node.js LoopBack APi FrameworkGetting Started with the Node.js LoopBack APi Framework
Getting Started with the Node.js LoopBack APi FrameworkJimmy Guerrero
 
Resting on your laurels will get you powned
Resting on your laurels will get you pownedResting on your laurels will get you powned
Resting on your laurels will get you pownedDinis Cruz
 
Build Modern Web Apps Using ASP.NET Web API and AngularJS
Build Modern Web Apps Using ASP.NET Web API and AngularJSBuild Modern Web Apps Using ASP.NET Web API and AngularJS
Build Modern Web Apps Using ASP.NET Web API and AngularJSTaiseer Joudeh
 
RESTful web APIs (build, document, manage)
RESTful web APIs (build, document, manage)RESTful web APIs (build, document, manage)
RESTful web APIs (build, document, manage)Cisco DevNet
 
Protecting Your APIs Against Attack & Hijack
Protecting Your APIs Against Attack & Hijack Protecting Your APIs Against Attack & Hijack
Protecting Your APIs Against Attack & Hijack CA API Management
 
Building Better Web APIs with Rails
Building Better Web APIs with RailsBuilding Better Web APIs with Rails
Building Better Web APIs with RailsAll Things Open
 

Similaire à spray: REST on Akka (Scala Days) (20)

APIdays San Francisco, 06/22/2013
APIdays San Francisco, 06/22/2013APIdays San Francisco, 06/22/2013
APIdays San Francisco, 06/22/2013
 
From Web APIs to Cross-Device Web Sites
From Web APIs to Cross-Device Web SitesFrom Web APIs to Cross-Device Web Sites
From Web APIs to Cross-Device Web Sites
 
SharePoint Data Anywhere and Everywhere by Chris Beckett - SPTechCon
SharePoint Data Anywhere and Everywhere by Chris Beckett - SPTechConSharePoint Data Anywhere and Everywhere by Chris Beckett - SPTechCon
SharePoint Data Anywhere and Everywhere by Chris Beckett - SPTechCon
 
REST-API introduction for developers
REST-API introduction for developersREST-API introduction for developers
REST-API introduction for developers
 
Soap and Rest
Soap and RestSoap and Rest
Soap and Rest
 
Advanced Web Development in PHP - Understanding REST API
Advanced Web Development in PHP - Understanding REST APIAdvanced Web Development in PHP - Understanding REST API
Advanced Web Development in PHP - Understanding REST API
 
Ibm_interconnect_restapi_workshop
Ibm_interconnect_restapi_workshopIbm_interconnect_restapi_workshop
Ibm_interconnect_restapi_workshop
 
Ruby Conf Preso
Ruby Conf PresoRuby Conf Preso
Ruby Conf Preso
 
REST - What's It All About? (SAP TechEd 2012, CD110)
REST - What's It All About? (SAP TechEd 2012, CD110)REST - What's It All About? (SAP TechEd 2012, CD110)
REST - What's It All About? (SAP TechEd 2012, CD110)
 
Birds Eye View on API Development - v1.0
Birds Eye View on API Development - v1.0Birds Eye View on API Development - v1.0
Birds Eye View on API Development - v1.0
 
Seattle StrongLoop Node.js Workshop
Seattle StrongLoop Node.js WorkshopSeattle StrongLoop Node.js Workshop
Seattle StrongLoop Node.js Workshop
 
automated-automation-of-rest-apis.pptx
automated-automation-of-rest-apis.pptxautomated-automation-of-rest-apis.pptx
automated-automation-of-rest-apis.pptx
 
Mike Taulty MIX10 Silverlight 4 Patterns Frameworks
Mike Taulty MIX10 Silverlight 4 Patterns FrameworksMike Taulty MIX10 Silverlight 4 Patterns Frameworks
Mike Taulty MIX10 Silverlight 4 Patterns Frameworks
 
Getting Started with the Node.js LoopBack APi Framework
Getting Started with the Node.js LoopBack APi FrameworkGetting Started with the Node.js LoopBack APi Framework
Getting Started with the Node.js LoopBack APi Framework
 
Resting on your laurels will get you powned
Resting on your laurels will get you pownedResting on your laurels will get you powned
Resting on your laurels will get you powned
 
Build Modern Web Apps Using ASP.NET Web API and AngularJS
Build Modern Web Apps Using ASP.NET Web API and AngularJSBuild Modern Web Apps Using ASP.NET Web API and AngularJS
Build Modern Web Apps Using ASP.NET Web API and AngularJS
 
RESTful web APIs (build, document, manage)
RESTful web APIs (build, document, manage)RESTful web APIs (build, document, manage)
RESTful web APIs (build, document, manage)
 
Protecting Your APIs Against Attack & Hijack
Protecting Your APIs Against Attack & Hijack Protecting Your APIs Against Attack & Hijack
Protecting Your APIs Against Attack & Hijack
 
Building Better Web APIs with Rails
Building Better Web APIs with RailsBuilding Better Web APIs with Rails
Building Better Web APIs with Rails
 
In app search 1
In app search 1In app search 1
In app search 1
 

Dernier

Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
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
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
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
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
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
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
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
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
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
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
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
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
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
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 

Dernier (20)

Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
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
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
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
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
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
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
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
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
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
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 

spray: REST on Akka (Scala Days)

  • 1. REST on Akka Scala Days April 17th, 2012
  • 3. What is spray? Vision: Provide the best toolkit for REST/HTTP and low-level network-IO on top of Akka
  • 4. What is spray? Vision: Provide the best toolkit for REST/HTTP and low-level network-IO on top of Akka • First released about 1 year ago
  • 5. What is spray? Vision: Provide the best toolkit for REST/HTTP and low-level network-IO 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? Vision: Provide the best toolkit for REST/HTTP and low-level network-IO on top of Akka • First released about 1 year ago • Principles: lightweight, async, non-blocking, actor-based, modular, few deps, testable • Philosophy: set of libraries, not framework
  • 8. Current State Transitioning from Akka 1.3 to Akka 2.0
  • 9. Current State Transitioning from Akka 1.3 to Akka 2.0 • spray 0.9.0 for Akka 1.3 released in March
  • 10. Current State Transitioning from Akka 1.3 to Akka 2.0 • spray 0.9.0 for Akka 1.3 released in March • spray 1.0-M1 for Akka 2.0 two weeks ago
  • 11. Current State Transitioning from Akka 1.3 to Akka 2.0 • spray 0.9.0 for Akka 1.3 released in March • spray 1.0-M1 for Akka 2.0 two weeks ago • Next: second milestone of spray 1.0
  • 12. Current State Transitioning from Akka 1.3 to Akka 2.0 • spray 0.9.0 for Akka 1.3 released in March • spray 1.0-M1 for Akka 2.0 two weeks ago • Next: second milestone of spray 1.0 Focus of this talk
  • 13. Components spray-routing spray-client spray-servlet spray-can spray-json spray-http spray-io
  • 14. Components spray-routing spray-client spray-servlet spray-can spray-json spray-http spray-io Low-level, “actorized” network IO
  • 15. Components spray-routing spray-client spray-servlet spray-can spray-json spray-http spray-io rich immutable HTTP model (no Akka)
  • 16. Components spray-routing spray-client spray-servlet spray-can spray-json low-level HTTP server and client spray-http spray-io
  • 17. Components spray-routing spray-client spray-servlet spray-can spray-json Servlet API adapter layer spray-http spray-io
  • 18. Components spray-routing spray-client DSL for server-side API construction spray-servlet spray-can spray-json spray-http spray-io
  • 19. Components spray-routing spray-client Complementary high- level HTTP client spray-servlet spray-can spray-json spray-http spray-io
  • 20. Components spray-routing spray-client spray-servlet spray-can spray-json straight JSON in Scala (no Akka) spray-http spray-io
  • 21. Components spray-routing spray-client Focus for the rest of the talk spray-servlet spray-can spray-json spray-http spray-io
  • 23. spray-routing • Runs on spray-servlet or spray-can
  • 24. spray-routing • Runs on spray-servlet or spray-can • Tool for building a “self-contained” API layer
  • 25. spray-routing • Runs on spray-servlet or spray-can • Tool for building a “self-contained” API layer • Central element: Routing DSL for defining web API behavior
  • 26. spray-routing • Runs on spray-servlet 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
  • 27. Basic Architecture Application Business Logic
  • 28. Basic Architecture REST API layer Application Routing Logic Business Logic
  • 29. Basic Architecture REST API layer Application HTTP Request Routing Logic Business Logic
  • 30. Basic Architecture REST API layer Application HTTP Request Action Routing Logic Business Logic
  • 31. Basic Architecture REST API layer Application HTTP Request Action domain Routing object ! Business Logic Logic
  • 32. Basic Architecture REST API layer Application HTTP Request Action domain Routing object ! Business Logic Logic Reply
  • 33. Basic Architecture REST API layer Application HTTP Request Action domain Routing object ! Business Logic Logic Reply
  • 34. Basic Architecture REST API layer Application HTTP Request Action domain Routing object ! Business Logic Logic HTTP Response Reply
  • 36. API Layer Responsibilities • Request routing based on method, path, query parameters, entity
  • 37. API Layer Responsibilities • Request routing based on method, path, query parameters, entity • (Un)marshalling to / from domain objects
  • 38. API Layer Responsibilities • Request routing based on method, path, query parameters, entity • (Un)marshalling to / from domain objects • Encoding / decoding (compression)
  • 39. API Layer Responsibilities • Request routing based on method, path, query parameters, entity • (Un)marshalling to / from domain objects • Encoding / decoding (compression) • Authentication / authorization
  • 40. API Layer Responsibilities • Request routing based on method, path, query parameters, entity • (Un)marshalling to / from domain objects • Encoding / decoding (compression) • Authentication / authorization • Caching and serving static content
  • 41. API Layer Responsibilities • Request routing based on method, path, query parameters, entity • (Un)marshalling to / from domain objects • Encoding / decoding (compression) • Authentication / authorization • Caching and serving static content • RESTful error handling
  • 43. API Building in spray • HTTP messages are actor messages
  • 44. API Building in spray • HTTP messages are actor messages class PingServiceActor extends Actor { def receive = { case HttpRequest(GET, "/ping", _, _, _) => sender ! HttpResponse(200, "PONG") } }
  • 45. API Building in spray • HTTP messages are actor messages class PingServiceActor extends Actor { def receive = { case HttpRequest(GET, "/ping", _, _, _) => sender ! HttpResponse(200, "PONG") } } • Could build services only via pattern-matching
  • 46. API Building in spray • HTTP messages are actor messages class PingServiceActor extends Actor { def receive = { case HttpRequest(GET, "/ping", _, _, _) => sender ! HttpResponse(200, "PONG") } } • Could build services only via pattern-matching • But: pattern-matching becomes awkward for more complex service definitions
  • 47. API Building in spray: DSL Simple example: class MyServiceActor extends Actor with Routing { def receive = receiveFromRoute { path("order" / HexIntNumber) { id => get { completeWith { "Received GET request for order " + id } } ~ put { completeWith { "Received PUT request for order " + id } } } } }
  • 49. sprays Routing DSL • Built from recombinant elements called “directives”
  • 50. sprays Routing DSL • Built from recombinant elements called “directives” • Concise, readable, maintainable
  • 51. sprays Routing DSL • Built from recombinant elements called “directives” • Concise, readable, maintainable • Highly composable
  • 52. sprays Routing DSL • Built from recombinant elements called “directives” • Concise, readable, maintainable • Highly composable • Type-safe
  • 53. sprays Routing DSL • Built from recombinant elements called “directives” • Concise, readable, maintainable • Highly composable • Type-safe • Easily extensible with custom constructs
  • 54. sprays Routing DSL • Built from recombinant elements called “directives” • Concise, readable, maintainable • Highly composable • Type-safe • Easily extensible with custom constructs • Directly interfaces with Akka API
  • 55. Routing Basics Routes in spray: type Route = RequestContext => Unit
  • 56. Routing Basics Routes in spray: type Route = RequestContext => Unit Explicit continuation- passing style
  • 57. Routing Basics Routes in spray: type Route = RequestContext => Unit Explicit continuation- passing style Central object: case class RequestContext( request: HttpRequest, ...) {   def complete(...) { ... }   def reject(...) { ... }   ... }
  • 58. Routing Basics The simplest route: ctx => ctx.complete("Say hello to spray")
  • 59. Routing Basics The simplest route: ctx => ctx.complete("Say hello to spray") or: _.complete("Say hello to spray")
  • 60. 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")
  • 61. 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)
  • 62. 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 } } }
  • 63. 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 } } }
  • 64. 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 } } }
  • 65. 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 } } }
  • 66. 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 }
  • 67. 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 } } }
  • 68. 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 } } }
  • 69. 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!
  • 70. 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
  • 71. 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,
  • 72. } } }~ } } 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") {
  • 73. } }~ 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") } } }
  • 75. Best Practices • Keep route structure clean and readable, pull out all logic into custom directives
  • 76. Best Practices • Keep route structure clean and readable, pull out all logic into custom directives • Don’t let API layer leak into application
  • 77. 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
  • 78. 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 • Use sbt-revolver + JRebel for fast dev turn- around
  • 80. There is more ... • SprayJsonSupport, LiftJsonSupport, TwirlSupport, ScalateSupport
  • 81. There is more ... • SprayJsonSupport, LiftJsonSupport, TwirlSupport, ScalateSupport • Asynchronous response push streaming
  • 82. There is more ... • SprayJsonSupport, LiftJsonSupport, TwirlSupport, ScalateSupport • Asynchronous response push streaming • Testing spray routes
  • 83. There is more ... • SprayJsonSupport, LiftJsonSupport, TwirlSupport, ScalateSupport • Asynchronous response push streaming • Testing spray routes • RESTful errors
  • 84. There is more ... • SprayJsonSupport, LiftJsonSupport, TwirlSupport, ScalateSupport • Asynchronous response push streaming • Testing spray routes • RESTful errors • spray-client
  • 85. There is more ... • SprayJsonSupport, LiftJsonSupport, TwirlSupport, ScalateSupport • Asynchronous response push streaming • Testing spray routes • RESTful errors • spray-client • spray-io
  • 87. What’s next? • release 1.0 featuring improved and simplified API for Akka 2.0
  • 88. What’s next? • release 1.0 featuring improved and simplified API for Akka 2.0 • Better and deeper documentation (follow Akkas model of treating docs as code)
  • 89. What’s next? • release 1.0 featuring improved and simplified API for Akka 2.0 • Better and deeper documentation (follow Akkas model of treating docs as code) • Coming features: deeper REST support, monitoring, request throttling, ...
  • 90. What’s next? • release 1.0 featuring improved and simplified API for Akka 2.0 • Better and deeper documentation (follow Akkas model of treating docs as code) • Coming features: deeper REST support, monitoring, request throttling, ... • Possibly: websockets, SPDY
  • 91. A few current sprayers ...
  • 92. Getting started • Main site & documentation: https://github.com/spray/spray/wiki • Mailing list: http://groups.google.com/group/spray-user • Twitter: @spraycc
  • 94. More
  • 95. 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 } } }
  • 96. 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) } }
  • 97. 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) } }
  • 98. 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) }
  • 99. 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) }
  • 100. Directives Operators are type-safe: val orderPath = path("order" / IntNumber)
  • 101. Directives Compiles? Operators are type-safe: val orderPath = path("order" / IntNumber)
  • 102. Directives Compiles? Operators are type-safe: val orderPath = path("order" / IntNumber) val dir = orderPath | get
  • 103. Directives Compiles? Operators are type-safe: val orderPath = path("order" / IntNumber) val dir = orderPath | get
  • 104. Directives Compiles? Operators are type-safe: val orderPath = path("order" / IntNumber) val dir = orderPath | get val dir = orderPath | path("[^/]+".r / DoubleNumber)
  • 105. Directives Compiles? Operators are type-safe: val orderPath = path("order" / IntNumber) val dir = orderPath | get val dir = orderPath | path("[^/]+".r / DoubleNumber)
  • 106. 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])
  • 107. 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])
  • 108. 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 ?)
  • 109. 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 ?)
  • 110. 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 }
  • 111. 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") } } }

Notes de l'éditeur

  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
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n