practical akka http - introduction
TRANSCRIPT
ITERATORSI T E RATORS @luksow
Practical Akka HTTPintroduction
Łukasz Sowa, XI Tricity Scala User Group
I T E RATORSITERATORSI T E RATORS @luksow
Hi, I'm Łukasz
● Co-founder, dev @ Iterators (https://iterato.rs)● Highly concurrent & distributed systems (MSA)● ScalaWAW organizer (please attend!)● Pizza, beer & football lover
● http://luksow.com● [email protected]● @luksow
ITERATORSI T E RATORS @luksow
What's in it for you?
● Learn– What Akka HTTP is
– Key architectural concepts
– When & how to use it
– How does it fit in the Scala ecosystem
● Takeaways– Beginners: ability to start using Akka HTTP
– Advanced: solid foundations for more exploring
I T E RATORSITERATORSI T E RATORS @luksow
Akka HTTP basicsboring facts
ITERATORSI T E RATORS @luksow
Akka HTTP – in definition
● Part of Akka project● HTTP toolkit (server- and client-side)● On top of akka-actor & akka-stream● Streams, reactive, backpressure, blah!● Not a framework – focus: integration layers● Multiple levels of abstraction (open API)● Scalable; max throughput, acceptable latency● Both for Java & Scala
ITERATORSI T E RATORS @luksow
Akka HTTP – in implementation
● Fully asynchronous & non-blocking● Actor-friendly but focused on higher-level
API● Lightweight● Modular, testable● Based on mature spray.io
ITERATORSI T E RATORS @luksow
Akka HTTP – in dates
● Spray.io (2011-03 – 2015-06 ✝?)– Bad chunked-requests support– Missing features (ex. websockets)– Hard to develop & debug
● Spray.io acquired by Typesafe (2013-10)● First preview - 0.4 (2014-06)
– Very experimental, practically unusable
● 'Good enough for evaluation and production' – 1.0 (2015-07)– No, not really, still very experimental and lacking
● Five months later - 2.0 (2015-12)– Oh sorry, we changed some interfaces, have a nice migration!
● Akka 2.4.2-RC3 (2016-02)– Akka HTTP included in main Akka project, only 'half experimental'
ITERATORSI T E RATORS @luksow
Akka HTTP – in parts
● akka-http-core– Low-level server & client-side HTTP implementation
● akka-http– High-level API: (un)marshalling, (de)compression, DSL
● akka-http-testkit– Utilities for testing server-side implementation
● akka-http-spray-json– Glue-code for (de)serialization from/to JSON with spray-json
● akka-http-xml– Glue-code for (de)serialization from/to XML with scala-xml
I T E RATORSITERATORSI T E RATORS @luksow
Inside Akka HTTPHTTP model, server, DSL,
client, (un)marshalling, testkit
I T E RATORSITERATORSI T E RATORS @luksow
HTTP model
● Fully immutable, case-class-based● Abstraction for most HTTP things (types!)● Little logic inside● Lots of predefined types – common media type,
status codes, encodings etc.● Open for extensions● Still very efficient parsing & rendering
● Drawback? Your clients and connected services have to obey the standard (and bugs happen too!)
I T E RATORSITERATORSI T E RATORS @luksow
HTTP model – examples (1)
I T E RATORSITERATORSI T E RATORS @luksow
HTTP model - examples (2)
I T E RATORSITERATORSI T E RATORS @luksow
HTTP model - examples (3)
I T E RATORSITERATORSI T E RATORS @luksow
Serving – the streams way
I T E RATORSITERATORSI T E RATORS @luksow
Serving – the functional way
I T E RATORSITERATORSI T E RATORS @luksow
Serving – the hard way
Flow[ByteString, ByteString, _]
I T E RATORSITERATORSI T E RATORS @luksow
Serving – example
Full example: https://github.com/theiterators/cors-buster
I T E RATORSITERATORSI T E RATORS @luksow
Serving – the nice way
I T E RATORSITERATORSI T E RATORS @luksow
Routing DSL
● Internal domain specific language for routing
● How most services are actually written● Layer to the application (business logic)● Type safe but flexible● Not just routing – behaviour definition● Very composable● Fun, powerful and looks sexy!
I T E RATORSITERATORSI T E RATORS @luksow
Routing DSL - example
I T E RATORSITERATORSI T E RATORS @luksow
Routing DSL – directives (1)
● type Route = RequestContext ⇒ Future[RouteResult]
● abstract class Directive[L]● def complete(m: ⇒
ToResponseMarshallable): StandardRoute● def reject(rejections: Rejection*):
StandardRoute● def fail(error: Throwable):
Future[RouteResult]
I T E RATORSITERATORSI T E RATORS @luksow
Routing DSL – directives (2)
● ~136 predefined directives● Roles: extracting, filtering, transforming
request or response, side-effecting● Create your own by composing (| and &
operators) or writing from scratch
● Beaware: it takes time to fully understand how directives work
I T E RATORSITERATORSI T E RATORS @luksow
Routing DSL – custom directive
I T E RATORSITERATORSI T E RATORS @luksow
Routing DSL – rejections
● Rejections– Are produced by directives– Travel down the routing structure
– Can be cancelled
– Must be handled if no route completes request– Can be extended– trait RejectionHandler extends (immutable.Seq[Rejection] ⇒
Option[Route])– Handling rejection = transforming it into response (probably
with some error code etc.)
– Ex. MethodRejection, AuthorizationFailedRejection, MissingCookieRejection, MissingQueryParamRejection
I T E RATORSITERATORSI T E RATORS @luksow
Routing DSL – failures
● Failures (or exceptions)– Are triggered by exceptions or fail(...)
– Travel up the routing structre
– Can be handled by handleExceptions directive or top-level ExceptionHandler
– trait ExceptionHandler extends PartialFunction[Throwable, Route]
– Can be used to simplify flow (not very nice) – ex. for validation
I T E RATORSITERATORSI T E RATORS @luksow
Client
● Connection-level client – Full control over connection and
request/response scheduling
● Host-level client– Akka manages connection pool to one
specific host
● Request-level– Akka performs all connection management
I T E RATORSITERATORSI T E RATORS @luksow
Connection-level client
● Stream-based● Enables
– HTTP persistent connection
– HTTP pipelining
I T E RATORSITERATORSI T E RATORS @luksow
Host-level client
● Stream-based● Some complexities around pool
configuration and materialization
I T E RATORSITERATORSI T E RATORS @luksow
Request-level client
● Super easy to use● What you usually need● Notice request-building DSL!
I T E RATORSITERATORSI T E RATORS @luksow
(Un)marshalling (1)
● Marshalling – high level → low (wire) level– ToEntityMarshaller[T]
– ToHeadersAndEntityMarshaller[T]– ToResponseMarshaller[T]
– ToRequestMarshaller[T]
● Unmarshalling – low (wire) level → high level– FromEntityUnmarshaller[T]
– FromMessageUnmarshaller[T]
– FromResponseUnmarshaller[T]
– FromRequestUnmarshaller[T]
– FromStringUnmarshaller[T]
– FromStrictFormFieldUnmarshaller[T]
I T E RATORSITERATORSI T E RATORS @luksow
(Un)marshalling (2)
● Many predefined (un)marshallers (also for generic types)
● Extensible● JSON and XML support in additional
packages● Type-class approach – implicit resolution● Cryptic error messages
I T E RATORSITERATORSI T E RATORS @luksow
Testkit
● Very simple and straightforward● Allows to assert responses returned for
given requests● Integrates well with specs2, ScalaTest
I T E RATORSITERATORSI T E RATORS @luksow
Everyday Akka HTTPsome additional remarks
I T E RATORSITERATORSI T E RATORS @luksow
Akka HTTP in Scala world (1)
● Again: it's not a framework● Not a competition for Play
– Akka HTTP is going to be Play's (2.5.X?) backend
● Competition: Spray.io, Finagle, Scalatra, Unfiltered?
● Backed by Lightbend (Typesafe)
I T E RATORSITERATORSI T E RATORS @luksow
Akka HTTP in Scala world (2)
● Where it excels– Integration layers
– Microservices
– Pure REST APIs
● Where it falls short– Fully-fledged web applications (with server-
side template generation)
– IMO still lacks maturity
I T E RATORSITERATORSI T E RATORS @luksow
Notable community projects
● https://github.com/softwaremill/akka-http-session
● https://github.com/hseeberger/akka-sse
● https://github.com/hseeberger/akka-http-json
● Not too many
● So roll up your sleeves! :)
● But integrates seamlessly with almost anything
● Lots of educational projects exist
I T E RATORSITERATORSI T E RATORS @luksow
Performance
● Spray.io's performance was impressive– 750K req/sec via Twitter
– More benchmarks by TechEmpower
● Akka HTTP 1.0 was roughly 10x slower● Akka HTTP 2.4.2-RC2 75% of Spray's perf
– “this is not the end of the performance work, we have only just begun”
● But those benchmarks, you know…
I T E RATORSITERATORSI T E RATORS @luksow
Conclusionstldr;
I T E RATORSITERATORSI T E RATORS @luksow
What was skipped?
● Streams stuff (persistent connections, pipelining, backpressure etc.)
● Low-level internals● SSL/TLS support● Very nice Websocket support● Probably bunch of other important things
I T E RATORSITERATORSI T E RATORS @luksow
What to remember?
● Akka HTTP is (probably) the hottest Scala HTTP toolkit● Built on very solid foundations● Features all the building blocks needed for well-
designed HTTP services● Provides both low- and high-level (DSLs!) interfaces
for almost everything● Reactive streams included● Still lacks maturity● Easy to start with but hard to master● Fun to use!
I T E RATORSITERATORSI T E RATORS @luksow
How to start?● Start coding right away
● Have fun
● Discover best practices along the way
● http://doc.akka.io/docs/akka-stream-and-http-experimental/current/scala/http/index.html
● http://doc.akka.io/api/akka-stream-and-http-experimental/2.0.3/
● https://github.com/theiterators/akka-http-microservice + tutorial
● https://github.com/theiterators/reactive-microservices + tutorial
● Lightbend Activator – search akka-http
● https://groups.google.com/forum/#!forum/akka-user
● https://gitter.im/akka/akka
● Sign up for a newsletter on http://luksow.com to get notified about big tutorial I'm preparing
I T E RATORSITERATORSI T E RATORS @luksow
Thanks!
● Łukasz Sowa● https://iterato.rs● http://luksow.com● [email protected]● @luksow
Questions?