building a reactive restful api with akka http & slick
TRANSCRIPT
![Page 1: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/1.jpg)
Codemotion 2015,Berlin, Germany
Building a
Reactive RESTful APIwith Akka Http & Slick
Dan Persa - @danpersa
![Page 3: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/3.jpg)
EUROPE’S LEADING ONLINE FASHION PLATFORM
15 countries3 fulfillment centers16+ million active customers2.2+ billion € revenue 2014130+ million visits per month9.000+ employees
Visit us: tech.zalando.com
![Page 4: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/4.jpg)
![Page 5: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/5.jpg)
![Page 6: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/6.jpg)
ZALANDOTECHNOLOGY
![Page 7: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/7.jpg)
![Page 8: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/8.jpg)
![Page 9: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/9.jpg)
500+Apps
800+ Tech employees
August
![Page 10: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/10.jpg)
![Page 11: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/11.jpg)
Conway’s Law
“organizations which design systems ...are constrained to produce designs which are copies of the communication structures of these organizations”
![Page 12: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/12.jpg)
ARCHITECTURE
AN ARCHITECTURE FOR INNOVATION
![Page 13: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/13.jpg)
API FIRSTRESTSAAS
MICRO SERVICESCLOUD
OPEN SOURCE
![Page 14: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/14.jpg)
![Page 15: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/15.jpg)
THE SHOP MONOLITH
![Page 16: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/16.jpg)
http://blog.codinghorror.com/new-programming-jargon/
We call it “Jimmy”
![Page 17: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/17.jpg)
Thousands of Java classes, undocumented featuresBusiness logic on all layers (including the database)
![Page 18: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/18.jpg)
MICROSERVICES
![Page 19: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/19.jpg)
Internet
LB
SKIPPERSKIPPER
SKIPPERSKIPPER
JIMMYMOSAIC
INNKEEPERINNKEEPER
INNKEEPERLB
REST APIs
![Page 20: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/20.jpg)
HIGHLY AVAILABLE0 DOWNTIMERELIABLEFAST
![Page 21: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/21.jpg)
INNKEEPER github.com/zalando/innkeeper
![Page 22: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/22.jpg)
API FIRSTREST
![Page 23: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/23.jpg)
FORMAL SPECIFICATION FOR RESTful APIs
The World's Most Popular Framework for APIs.
![Page 24: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/24.jpg)
![Page 25: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/25.jpg)
REST RESOURCES
GET /routesGET /routes/{id}POST /routesDELETE /routes/{id}
GET /updated-routes/{id}
![Page 26: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/26.jpg)
GOING REACTIVE
![Page 27: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/27.jpg)
![Page 28: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/28.jpg)
MODEL DBCONTROLLER
BUFFERBUFFERDB RecordsDTOsJSON
CLIENT
TRADITIONAL APPLICATION
HTTP Request Method Call SQL
Blocking IO
![Page 29: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/29.jpg)
MODEL DBCONTROLLER
DB StreamDTOsJSON
CLIENT
REACTIVE APPLICATION
HTTP Request Method Call SQL
Non-Blocking IO
StreamStreamStream
![Page 30: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/30.jpg)
ScalaTypesafeComposable
Meet
![Page 31: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/31.jpg)
Separation of I/0ResilienceReactive Streams
Meet
![Page 32: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/32.jpg)
def routesModifiedSince(localDateTime: LocalDateTime): DatabasePublisher[RouteRow] = {
}
val routesTable = TableQuery[RoutesTable]
val q = for { routeRow <- routesTable if (routeRow.createdAt > localDateTime | routeRow.deletedAt > localDateTime)} yield routeRow
db.stream { q.result }
![Page 33: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/33.jpg)
ComposableMaterializableReactive Streams
Meet
Streams
![Page 34: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/34.jpg)
import akka.stream.scaladsl.Source
def findRoutesModifiedSince(localDateTime: LocalDateTime): Source[Route, Unit] = {
}
Source(
).mapConcat(_.toList)
routesRepo.selectModifiedSince(localDateTime).mapResult { row =>
}
row.id.map { id => Route( id = id, route = row.routeJson.parseJson.convertTo[NewRoute], row.createdAt, row.deletedAt )}
![Page 35: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/35.jpg)
val route = path("hello") { get { complete { <h1>Hello World</h1> } } }
Meet
Http
![Page 36: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/36.jpg)
object Main extends App {
}
implicit val system = ActorSystem("my-system")implicit val materializer = ActorMaterializer()val route = ...val bindingFuture = Http().bindAndHandle(route, "localhost", 8080)...
![Page 37: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/37.jpg)
Innkeeper’s AKKA HTTP Routesval route = path("updated-routes" / Rest) { lastModifiedString => get { complete(…) } } ~ path("routes") { get { complete(…) } ~ post { complete(…) } } ~ path("routes" / LongNumber) { id => get { … } ~ delete { … } }
![Page 38: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/38.jpg)
path("routes") { get {
complete { HttpResponse(
) } }}
entity = HttpEntity.Chunked( MediaTypes.`application/json`, chunkedStreamSource )
val chunkedStreamSource = jsonService.sourceToJsonSource(routesService.allRoutes)
![Page 39: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/39.jpg)
def sourceToJsonSource[T](source: Source[T, Unit]) (implicit writer: JsonWriter[T]):
Source[ChunkStreamPart, ((Unit, Unit), Unit)] = {
val commaSeparatedRoutes: Source[ChunkStreamPart, Unit] = source .map(t => Some(t.toJson.compactPrint)) .scan[Option[ChunkStreamPart]](None)({ case (None, Some(sourceElement)) => Some(ChunkStreamPart(sourceElement)) case (_, Some(sourceElement)) => Some(ChunkStreamPart(s", $sourceElement")) }) .mapConcat(_.toList)
Source.single(ChunkStreamPart("[")) ++ commaSeparatedRoutes ++ Source.single(ChunkStreamPart("]")) }
![Page 40: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/40.jpg)
SAAS
![Page 41: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/41.jpg)
OAUTH
![Page 42: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/42.jpg)
val route: RequestContext => Future[RouteResult] = authenticationToken { token => authenticate(token, authService) { authenticatedUser => path("updated-routes" / Rest) { lastModifiedString => get { hasOneOfTheScopes(authenticatedUser)(scopes.READ) { ...
![Page 43: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/43.jpg)
import akka.http.scaladsl._import akka.http.scaladsl.server.directives.HeaderDirectives._
trait OAuthDirectives { def authenticationToken: Directive1[String] = headerValue(optionalValue("authorization")) | reject {
AuthenticationFailedRejection( CredentialsMissing, HttpChallenge("", "")
) }...
![Page 44: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/44.jpg)
CLOUD
![Page 45: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/45.jpg)
STUPS.IO
![Page 46: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/46.jpg)
FROM zalando/openjdk:8u45-b14-5MAINTAINER Team Spearheads <[email protected]>
EXPOSE 8080
RUN mkdir -p /opt/innkeeper
ADD target/scala-2.11/innkeeper-assembly-0.0.1.jar /opt/innkeeper/
WORKDIR /opt/innkeeper
ENTRYPOINT java $(java-dynamic-memory-opts) -Dinnkeeper.env=prod -server -jar innkeeper-assembly-0.0.1.jar
![Page 47: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/47.jpg)
docker:sbt assemblydocker build -t innkeper:latest-SNAPSHOT .
docker-push:docker push innkeper:latest-SNAPSHOT
docker-run:docker run -p 8080:8080 -t innkeper:latest-SNAPSHOT
test-db:docker run -e POSTGRES_PASSWORD=innkeeper-test -e
POSTGRES_USER=innkeeper-test -p 5433:5432 postgres:9.4
tick:senza create senza.yaml tick latest-SNAPSHOT
tock:senza create senza.yaml tock latest-SNAPSHOT
![Page 48: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/48.jpg)
OPENSOURCE
![Page 49: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/49.jpg)
github.com/zalando/innkeeper
![Page 50: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/50.jpg)
DOOSF
![Page 51: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/51.jpg)
RADICAL AGILITY
TRUSTINSTEAD OF CONTROL
![Page 52: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/52.jpg)
![Page 53: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/53.jpg)
![Page 54: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/54.jpg)
# use Docker-based container (instead of OpenVZ)sudo: false
cache: directories: - $HOME/.sbt - $HOME/.ivy2
language: scala
script: - sbt ++$TRAVIS_SCALA_VERSION test - sbt ++$TRAVIS_SCALA_VERSION it:test
# Trick to avoid unnecessary cache updates - find $HOME/.sbt -name "*.lock" | xargs rm
scala: - 2.11.7jdk: - oraclejdk8
addons: postgresql: "9.4"
before_script: - psql -c 'CREATE ROLE innkeepertest superuser login createdb;' -U postgres - psql -c 'CREATE DATABASE innkeepertest;' -U postgres
![Page 55: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/55.jpg)
NEXTSTEPS
![Page 56: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/56.jpg)
APPLICATION LOGS: SCALYR
![Page 57: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/57.jpg)
TODO: Screenshot
ZMON
![Page 58: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/58.jpg)
Where to Find Us:Tech Blog: tech.zalando.com
GitHub: github.com/zalando
Innkeeper: github.com/zalando/innkeeper
Twitter: @ZalandoTech
Instagram: zalandotech
Jobs: http://tech.zalando.com/jobs
![Page 59: Building a Reactive RESTful API with Akka Http & Slick](https://reader035.vdocuments.mx/reader035/viewer/2022081505/587f06091a28abc26f8b4db3/html5/thumbnails/59.jpg)
THANK YOU!QUESTIONS?