akka http , routes, streams with scala

12
Gentle Introduction to Akka Http , Streams and Routes Akka-HTTP MeetUp Aug 31,2015

Upload: jerry-kuru

Post on 21-Jan-2017

1.008 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Akka Http , Routes, Streams with Scala

Gentle Introduction to Akka Http , Streams and Routes

Akka-HTTP MeetUp Aug 31,2015

Page 2: Akka Http , Routes, Streams with Scala

Great Talk from Mathias

❖ Akka HTTP — The What, Why and How

❖ https://newcircle.com/s/post/1701/akka_http_the_what_why_and_how_mathias_doenitz_video

❖ https://www.youtube.com/watch?v=y_slPbktLr0

Page 3: Akka Http , Routes, Streams with Scala

Core Take away• Stream

• An active process that involves moving and transforming data.

• Element

An element is the processing unit of streams. All operations transform and transfer elements from upstream to downstream.

• Back-pressure

A means of flow-control, a way for consumers of data to notify a producer about their current availability, effectively slowing down the upstream producer to match their consumption speeds. In the context of Akka Streams back-pressure is always understood as non-blocking and asynchronous.

• Non-Blocking

Means that a certain operation does not hinder the progress of the calling thread, even if it takes long time to finish the requested operation.

• Processing Stage

The common name for all building blocks that build up a Flow or FlowGraph. Examples of a processing stage would be operations like map(), filter(), stages added by transform() like PushStage, PushPullStage, StatefulStage and graph junctions like Merge or Broadcast.

Page 4: Akka Http , Routes, Streams with Scala

Core Take away• Source : A processing stage with exactly one output, emitting data elements whenever

downstream processing stages are ready to receive them.

• Sink : A processing stage with exactly one input, requesting and accepting data elements possibly slowing down the upstream producer of elements

• Flow : A processing stage which has exactly one input and output, which connects its up- and downstreams by transforming the data elements flowing through it.

• RunnableGraph

• A Flow that has both ends "attached" to a Source and Sink respectively, and is ready to be run()

• It is important to remember that even after constructing the RunnableGraph by connecting all the source, sink and different processing stages, no data will flow through it until it is materialized.

• Materialization : Is the process of allocating all resources needed to run the computation described by a Flow (in Akka Streams this will often involve starting up Actors).

Page 5: Akka Http , Routes, Streams with Scala

Example

❖ http://docs.akkahttprest.apiary.io/#reference/users/current-user-interaction

Page 6: Akka Http , Routes, Streams with Scala

Http().bindAndHandle(routes, httpInterface, httpPort)

We know we need Source, Sink and Flow Handler with ActorMaterializer to Materializer ?

What is Source ? -

Incoming request is Source [HTTP and TCP]

What is Sink ?

OutGoing response is Sink [HTTP and TCP]

What is Flow Handler ?

Routes which is a Directives

Key Points

• As an alternative Akka HTTP provides a flexible DSL for expressing your service behavior as a structure of composable elements(called Directives) in a concise and readable way.

• Directives are assembled into a so called route structure which, at its top-level, forms a handler Flow (or, alternatively, an async handler function) that can be directly supplied to a bind call.

• The conversion from Route to flow can either be invoked explicitly using Route.handlerFlow or, otherwise, the conversion is also provided implicitly by RouteResult.route2HandlerFlow [1].

Page 7: Akka Http , Routes, Streams with Scala

What is Routes?The "Route" is the central concept of Akka HTTP's Routing DSL.

type Route = RequestContext ⇒ Future[RouteResult]

It's a simple alias for a function turning a RequestContext into a Future[RouteResult].

Generally when a route receives a request (or rather a RequestContext for it) it can do one of these things:

• Complete the request by returning the value of requestContext.complete(...)

• Reject the request by returning the value of requestContext.reject(...) (see Rejections)

• Fail the request by returning the value of requestContext.fail(...) or by just throwing an exception (see Exception Handling)

• Do any kind of asynchronous processing and instantly return a Future[RouteResult] to be eventually completed later

Page 8: Akka Http , Routes, Streams with Scala

RouteResult & Composing RoutesRouteResult is a simple abstract data type (ADT) that models the possible non-error results of a Route. It is defined as such:

1 sealed trait RouteResult

3 object RouteResult {

4 final case class Complete(response: HttpResponse) extends RouteResult

5 final case class Rejected(rejections: immutable.Seq[Rejection]) extends RouteResult

6 }

Usually you don't create any RouteResult instances yourself, but rather rely on the pre-defined RouteDirectives (like complete, reject or redirect) or the respective methods on the RequestContext instead.

Composing Routes There are three basic operations we need for building more complex routes from simpler ones:

• Route transformation, which delegates processing to another, "inner" route but in the process changes some properties of either the incoming request, the outgoing response or both

• Route filtering, which only lets requests satisfying a given filter condition pass and rejects all others

• Route chaining, which tries a second route if a given first one was rejected

The last point is achieved with the concatenation operator ~, which is an extension method that becomes available when you import the Directive [import akka.http.scaladsl.server.Directives.].

Page 9: Akka Http , Routes, Streams with Scala

The Routing TreeThe Routing Tree

Essentially, when you combine directives and custom routes via nesting and the ~ operator, you build a routing structure that forms a tree. When a request comes in it is injected into this tree at the root and flows down through all the branches in a depth-first manner until either some node completes it or it is fully rejected.

Consider this schematic example:1 val route =2 a {3 b {4 c {5 ... // route 16 } ~7 d {8 ... // route 29 } ~10 ... // route 311 } ~12 e {13 ... // route 414 }15 }

Here five directives form a routing tree.

• Route 1 will only be reached if directives a, b and c all let the request pass through.

• Route 2 will run if a and b pass, c rejects and d passes.

• Route 3 will run if a and b pass, but c and d reject

Page 10: Akka Http , Routes, Streams with Scala

Core ❖ What is a Route ?

❖ http://doc.akka.io/docs/akka-stream-and-http-experimental/1.0/scala/http/routing-dsl/routes.html#routes

❖ What is Routing DSL Overview ?

❖ http://doc.akka.io/docs/akka-stream-and-http-experimental/1.0/scala/http/routing-dsl/overview.html

Page 11: Akka Http , Routes, Streams with Scala

What is a Akka Message Dispatcher ?• Dispatchers

• An Akka MessageDispatcher is what makes Akka Actors "tick", it is the engine of the machine so to speak. All MessageDispatcher implementations are also an ExecutionContext, which means that they can be used to execute arbitrary code, for instance Futures.

my-dispatcher {2 # Dispatcher is the name of the event-based dispatcher3 type = Dispatcher4 # What kind of ExecutionService to use5 executor = "fork-join-executor"6 # Configuration for the fork join pool7 fork-join-executor {8 # Min number of threads to cap factor-based parallelism number to9 parallelism-min = 210 # Parallelism (threads) ... ceil(available processors * factor)11 parallelism-factor = 2.012 # Max number of threads to cap factor-based parallelism number to13 parallelism-max = 1014 }15 # Throughput defines the maximum number of messages to be16 # processed per actor before the thread jumps to the next actor.17 # Set to 1 for as fair as possible.18 throughput = 10019 }

Page 12: Akka Http , Routes, Streams with Scala

More Examples

❖ https://dzone.com/articles/building-rest-service-scala

❖ http://www.duhoka-min.net