Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Akka http 2

721 views

Published on

Akka Http 2 brings the power of Akka Actors to the web. It is a web server that can delegate to Akka Actors and builds on Akka Streams.

Published in: Software
  • Be the first to comment

Akka http 2

  1. 1. AKKA HTTP A.K.A. SPRAY 2.0 Présenté par Jean Detoeuf / @thebignet
  2. 2. JEAN DETOEUF DÉVELOPPEUR Passionné de nouvelles technologies #jvm #docker #craftmanship #rpi #diy
  3. 3. AVERTISSEMENT Je ne suis pas un expert en Scala Soyez sympas ^^
  4. 4. PROJET EN COURS DE MATURATION version lors de cette présentation2.0.1 mélange entre Spray et Akka J'ai eu l'idée de cette présentation à la version 1.0, il était temps !
  5. 5. AKKA STREAMS Présenté au SLUG par en février 2015Frédéric Masion Source ~> Flow ~> Sink Source décrit une source de données Flow représente une transformation de ces données Sink une opération terminale
  6. 6. AKKA STREAMS Source ~> Flow1 ~> Flow2a ~> Sink ~> Flow2b Fan-out / Fan-in
  7. 7. AKKA HTTP Constuit sur Akka Streams Internet est un tuyau rempli de chatons
  8. 8. AKKA HTTP Flow[HttpRequest, HttpResponse]
  9. 9. AKKA HTTP Client et serveur Mettre des acteurs sur HTTP
  10. 10. MODULES akka-http-spray-json akka-http-xml akka-http-testkit akka-http akka-http-core
  11. 11. C'EST BON, MONTRE-MOI LE CODE Les exemples sont pour la plupart tirés de la documentation d'Akka
  12. 12. EXEMPLE SIMPLE import akka.http.scaladsl.Http import akka.http.scaladsl.marshallers.xml.ScalaXmlSupport._ import akka.http.scaladsl.server.Directives._ import akka.stream.ActorMaterializer object Main extends App { implicit val system = ActorSystem("my-system") implicit val materializer = ActorMaterializer() implicit val ec = system.dispatcher val route = path("hello") { get { complete { <h1>Say hello to akka-http</h1> } } } val bindingFuture = Http().bindAndHandle(route, "localhost", 8080) println(s"Server online at http://localhost:8080/nPress RETURN to stop...") Console.readLine() // for the future transformations bindingFuture .flatMap(_.unbind()) // trigger unbinding from the port .onComplete(_ ⇒ system.shutdown()) // and shutdown when done }
  13. 13. EXEMPLE SIMPLE import akka.http.scaladsl.Http import akka.http.scaladsl.marshallers.xml.ScalaXmlSupport._ import akka.http.scaladsl.server.Directives._ import akka.stream.ActorMaterializer object Main extends App { implicit val system = ActorSystem("my-system") implicit val materializer = ActorMaterializer() implicit val ec = system.dispatcher val route = path("hello") { get { complete { <h1>Say hello to akka-http</h1> } } } val bindingFuture = Http().bindAndHandle(route, "localhost", 8080) println(s"Server online at http://localhost:8080/nPress RETURN to stop...") Console.readLine() // for the future transformations bindingFuture .flatMap(_.unbind()) // trigger unbinding from the port .onComplete(_ ⇒ system.shutdown()) // and shutdown when done }
  14. 14. EXEMPLE SIMPLE import akka.http.scaladsl.Http import akka.http.scaladsl.marshallers.xml.ScalaXmlSupport._ import akka.http.scaladsl.server.Directives._ import akka.stream.ActorMaterializer object Main extends App { implicit val system = ActorSystem("my-system") implicit val materializer = ActorMaterializer() implicit val ec = system.dispatcher val route = path("hello") { get { complete { <h1>Say hello to akka-http</h1> } } } val bindingFuture = Http().bindAndHandle(route, "localhost", 8080) println(s"Server online at http://localhost:8080/nPress RETURN to stop...") Console.readLine() // for the future transformations bindingFuture .flatMap(_.unbind()) // trigger unbinding from the port .onComplete(_ ⇒ system.shutdown()) // and shutdown when done }
  15. 15. EXEMPLE SIMPLE import akka.http.scaladsl.Http import akka.http.scaladsl.marshallers.xml.ScalaXmlSupport._ import akka.http.scaladsl.server.Directives._ import akka.stream.ActorMaterializer object Main extends App { implicit val system = ActorSystem("my-system") implicit val materializer = ActorMaterializer() implicit val ec = system.dispatcher val route = path("hello") { get { complete { <h1>Say hello to akka-http</h1> } } } val bindingFuture = Http().bindAndHandle(route, "localhost", 8080) println(s"Server online at http://localhost:8080/nPress RETURN to stop...") Console.readLine() // for the future transformations bindingFuture .flatMap(_.unbind()) // trigger unbinding from the port .onComplete(_ ⇒ system.shutdown()) // and shutdown when done }
  16. 16. MARSHALLING/UNMARSHALLING
  17. 17. MARSHALLING/UNMARSHALLING Comment passer d'un flux HTTP à Scala et inversement ?
  18. 18. MARSHALLING Marshallers prédéfinis Array[Byte] ByteString Array[Char] String akka.http.scaladsl.model.FormData akka.http.scaladsl.model.MessageEntity T <: akka.http.scaladsl.model.Multipart T si ToEntityMarshaller[T] est présent
  19. 19. MARSHALLING Résolution implicite Si le type ToEntityMarshaller[T] est défini, il est utilisé
  20. 20. UNMARSHALLING Unmarshallers prédéfinis Byte Short Int Long Float Double Boolean Array[Byte] ByteString Array[Char] String akka.http.scaladsl.model.FormData
  21. 21. ROUTAGE
  22. 22. LOW-LEVEL import akka.http.scaladsl.Http import akka.http.scaladsl.model.HttpMethods._ import akka.http.scaladsl.model._ import akka.stream.ActorMaterializer implicit val system = ActorSystem() implicit val materializer = ActorMaterializer() val requestHandler: HttpRequest => HttpResponse = { case HttpRequest(GET, Uri.Path("/"), _, _, _) => HttpResponse(entity = HttpEntity(ContentTypes.`text/html(UTF-8)` , "Hello world!")) case HttpRequest(GET, Uri.Path("/ping"), _, _, _) => HttpResponse(entity = "PONG!") case HttpRequest(GET, Uri.Path("/crash"), _, _, _) => sys.error("BOOM!") case _: HttpRequest => HttpResponse(404, entity = "Unknown resource!") } Http().bindAndHandleSync(requestHandler, "localhost", 8080)
  23. 23. HIGH-LEVEL import akka.http.scaladsl.Http import akka.http.scaladsl.marshallers.xml.ScalaXmlSupport._ import akka.http.scaladsl.server.Directives._ import akka.stream.ActorMaterializer implicit val system = ActorSystem() implicit val materializer = ActorMaterializer() val route = get { pathSingleSlash { complete { <html> <body>Hello world!</body> </html> } } ~ path("ping") { complete("PONG!") } ~ path("crash") { sys.error("BOOM!") } }
  24. 24. // `route` will be implicitly converted to `Flow` using `RouteResult .route2HandlerFlow` Http().bindAndHandle(route, "localhost", 8080)
  25. 25. DIRECTIVES
  26. 26. DIRECTIVES Intercepte la requête Filtrage de la requête Transformation de la requête ou réponse Extraire des informations
  27. 27. EXEMPLE val route = path("order" / IntNumber) { id => (get | put) { extractMethod { m => complete(s"Received ${m.name} request for order $id") } } }
  28. 28. EXEMPLE 2 val orderGetOrPutWithMethod = path("order" / IntNumber) & (get | put) & extractMethod val route = orderGetOrPutWithMethod { (id, m) => complete(s"Received ${m.name} request for order $id") }
  29. 29. et PATHMATCHER val matcher: PathMatcher1[Option[Int]] = "foo" / "bar" / "X" ~ IntNumber.? / ("edit" | "create") Intercepte les chemins suivants : foo/bar/X42/edit foo/bar/X/create
  30. 30. EXTRACTION CASE CLASS case class Color(red: Int, green: Int, blue: Int) val route = path("color") { parameters('red.as[Int], 'green.as[Int], 'blue.as[Int]).as(Color) { color => // utiliser color } }
  31. 31. VALIDATION CASE CLASS case class Color(name: String, red: Int, green: Int, blue: Int) { require(!name.isEmpty, "color name must not be empty") require(0 <= red && red <= 255, "red color component must be betwe en 0 and 255") require(0 <= green && green <= 255, "green color component must be between 0 and 255") require(0 <= blue && blue <= 255, "blue color component must be be tween 0 and 255") } ValidationRejection si require ne passe pas Par défaut : 400 Bad Request
  32. 32. TESTS
  33. 33. Pour la route suivante val smallRoute = get { pathSingleSlash { complete { "Hello World !" } } ~ path("ping") { complete("PONG !") } } Test "Hello World ! non renvoyé sur /" in { Get() ~> smallRoute ~> check { status === StatusCodes.OK responseAs[String] shouldEqual "Hello World !" } }
  34. 34. Pour la même route ... val smallRoute = get { pathSingleSlash { complete { "Hello World !" } } ~ path("ping") { complete("PONG !") } } Test "GET sur chemin inconnu non pris en compte" in { Get("/pouet") ~> smallRoute ~> check { handled shouldBe false } }
  35. 35. VARIABLES UTILISABLES DANS LES TESTS entityAs handled header response status entre autres ...
  36. 36. CLIENT val responseFuture: Future[HttpResponse] = Http().singleRequest(HttpRequest(uri = "http://akka.io"))
  37. 37. QUESTIONS ?
  38. 38. MERCI POUR VOTRE ÉCOUTE Cette présentation : @thebignet thebignet thebignet talk-akka-http

×