SlideShare a Scribd company logo
1 of 33
Download to read offline
Lightbend Lagom
Microservices “Just Right”
Mirco Dotta
@mircodotta
Scala Days NYC - May 10, 2016
Lagom - [lah-gome]
Adequate, sufficient, just right
Agenda
● Why Lagom?
● Lagom dive in
○ Development Environment
○ Service API
○ Persistence API
● Running in Production
Why Lagom?
● Opinionated
● Developer experience matters!
○ No brittle script to run your services
○ Inter-service communication just works
○ Services are automatically reloaded on code change
● Takes you through to production deployment
● sbt build tool (developer experience)
● Play 2.5
● Akka 2.4 (clustering, streams, persistence)
● Cassandra (default data store)
● Jackson (JSON serialization)
● Guice (DI)
● Architectural Concepts: immutability, Event Sourcing/CQRS,
circuit breakers
Under the hood
Enough slides,
Demo time
Anatomy of a Lagom project
● sbt build
● Scala 2.11 and JDK8
● Each service definition is split into two sbt projects:
○ api
○ Implementation
Service API
Service definition
trait HelloService extends Service {
override def descriptor(): Descriptor = {
named("helloservice").`with`(
namedCall("/hello", sayHello _)
)
}
def sayHello(): ServiceCall[String, String]
}
// this source is placed in your api project
ServiceCall explained
● ServiceCall can be invoked when consuming a service:
○ Request: type of incoming request message (e.g. String)
○ Response: type of outgoing response message (e.g. String)
● JSON is the default serialization format for request/response messages
● There are two kinds of request/response messages:
○ Strict
○ Streamed
trait ServiceCall[Request, Response] {
def invoke(request: Request): Future[Response]
}
Strict Messages
Strict messages are fully buffered into memory
override def descriptor(): Descriptor = {
named("friendservice").`with`(
pathCall("/users/:userId/friends", addFriend _)
)
}
def addFriend(userId: String): ServiceCall[FriendId, NotUsed]
Streamed Messages
override def descriptor(): Descriptor = {
named("clock").`with`(
pathCall("/tick/:interval", tick())
)
}
def tick(): ServiceCall[String, Source[String, _]]
● A streamed message is of type Source (an Akka streams API)
● It allows asynchronous streaming and handling of messages
● Lagom will select transport protocol (currently WebSockets)
Remember the Service definition?
trait HelloService extends Service {
override def descriptor(): Descriptor = {
named("helloservice").`with`(
namedCall(sayHello _)
)
}
def sayHello(): ServiceCall[String, String]
}
// this source is placed in your api project
Here is the Service implementation
class HelloServiceImpl extends HelloService {
override def sayHello(): ServiceCall[String, String] {
name => Future.successful(s"Hello, $name!")
}
}
// this source is placed in your implementation project
Inter-service communication
class MyServiceImpl @Inject()(helloService: HelloService)
(implicit ec: ExecutionContext) extends MyService {
override def sayHelloLagom(): ServiceCall[NotUsed, String] = unused => {
val response = helloService.sayHello().invoke("Lagom")
response.map(answer => s"Hello service said: $answer")
}
}
Persistence API
Principles
● Each service owns its data
○ Only the service has direct access to the DB
● We advocate the use of Event Sourcing (ES) and CQRS
○ ES: Capture all state’s changes as events
○ CQRS: separate models for write and read
Benefits of Event Sourcing/CQRS
● Allows you to time travel
● Audit log
● Future business opportunities
● No need for ORM
● No database migration script, ever
● Performance & Scalability
● Testability & Debuggability
Event Sourcing: Write Side
● Create your own Command and Event classes
● Subclass PersistentEntity
○ Define Command and Event handlers
○ Can be accessed from anywhere in the cluster
○ (corresponds to an Aggregate Root in DDD)
Event Sourcing: Example
Create the Command classes
sealed trait FriendCommand extends Jsonable
case class AddFriend(friendUserId: String) extends
PersistentEntity.ReplyType[Done] with FriendCommand
// more friend commands
Event Sourcing: Example cont’d
Create the Event classes
sealed trait FriendEvent extends Jsonable
case class FriendAdded(userId: String, friendId: String,
timestamp: Instant = Instant.now()) extends FriendEvent
// more friend events
Event Sourcing: Example cont’d
class FriendEntity extends
PersistentEntity[FriendCommand, FriendEvent, FriendState] {
def initialBehavior(snapshotState: Optional[FriendState]): Behavior =
// TODO: define command and event handlers
}
Create a subclass of PersistentEntity
Event Sourcing: Example cont’d
val b: Behavior = newBehaviorBuilder(/*...*/)
b.setCommandHandler(classOf[AddFriend],
(cmd: AddFriend, ctx: CommandContext[Done]) => state.user match {
case None =>
ctx.invalidCommand(s"User ${entityId} is not created")
ctx.done()
case Some(user) =>
ctx.thenPersist(FriendAdded(user.userId, cmd.friendUserId),
(evt: FriendAdded) => ctx.reply(Done))
})
b.setEventHandler(classOf[FriendAdded],
(evt: FriendAdded) => state.addFriend(evt.friendId))
Event Sourcing: Example cont’d
No side-effects in the event handler!
Event Sourcing: Example cont’d
Create the State class
case class FriendState(user: Option[User]) extends Jsonable {
def addFriend(friendUserId: String): FriendState = user match {
case None => throw new IllegalStateException(
"friend can't be added before user is created")
case Some(user) =>
val newFriends = user.friends :+ friendUserId
FriendState(Some(user.copy(friends = newFriends)))
}
}
class FriendServiceImpl @Inject() (persistentEntities: PersistentEntityRegistry)
(implicit ec: ExecutionContext) extends FriendService {
// at service startup we must register the needed entities
persistentEntities.register(classOf[FriendEntity])
def addFriend(userId: String): ServiceCall[FriendId, NotUsed] = request => {
val ref = persistentEntities.refFor(classOf[FriendEntity], userId)
ref.ask[Done, AddFriend](AddFriend(request.friendId))
}
// ...
}
Event Sourcing: Example cont’d
Event Sourcing: Read Side
● Tightly integrated with Cassandra
● Create the query tables:
○ Subclass CassandraReadSideProcessor
○ Consumes events produced by the PersistentEntity and
updates tables in Cassandra optimized for queries
● Retrieving data: Cassandra Query Language
○ e.g., SELECT id, title FROM postsummary
Running in Production
● sbt-native packager is used to produce zip, MSI, RPM, Docker
● Lightbend ConductR* (our container orchestration tool)
● Lightbend Reactive Platform*
○ Split Brain Resolver (for Akka cluster)
○ Lightbend Monitoring
*Requires a Lightbend subscription (ConductR is free to use during development)
Current[Lagom]
● Current version is 1.0.0-M2
○ 1.0 soon
● Java API, but no Scala API yet
○ We are working on the Scala API
○ But using Scala with the Java API works well! https:
//github.com/dotta/activator-lagom-scala-chirper
Future[Lagom]
● Maven support
● Message broker integration
● Scala API
● Support for other cluster orchestration tools
● Support for writing integration tests
● Swagger integration
○ Which also removes binary coupling!
Next: Seq[Step]
● Try Lagom yourself
○ https://lightbend.com/lagom
● Using Scala with Lagom
○ https://github.com/dotta/activator-lagom-scala-chirper
● Lagom on Github
○ https://github.com/lagom/lagom
● Read Jonas Bonér's free book Reactive Services Architecture
○ https://lightbend.com/reactive-microservices-architecture
● Great presentation by Greg Young on why you should use ES
○ https://www.youtube.com/watch?v=JHGkaShoyNs
Thank you for listening!
@mircodotta
@lagom
override def descriptor(): Descriptor = {
named("friendservice").`with`(
namedCall("/users", createUser _),
pathCall("/users/:id", getUser _),
restCall(Method.POST, "/users/:userId/friends", addFriend _)
)
}
def createUser(): ServiceCall[User, NotUsed]
def getUser(id: String): ServiceCall[NotUsed, User]
def addFriend(userId: String): ServiceCall[FriendId, NotUsed]
Different kinds of service call descriptors

More Related Content

What's hot

Introduction to Scala Macros
Introduction to Scala MacrosIntroduction to Scala Macros
Introduction to Scala MacrosKnoldus Inc.
 
Above the clouds: introducing Akka
Above the clouds: introducing AkkaAbove the clouds: introducing Akka
Above the clouds: introducing Akkanartamonov
 
Akka Actor presentation
Akka Actor presentationAkka Actor presentation
Akka Actor presentationGene Chang
 
Developing distributed applications with Akka and Akka Cluster
Developing distributed applications with Akka and Akka ClusterDeveloping distributed applications with Akka and Akka Cluster
Developing distributed applications with Akka and Akka ClusterKonstantin Tsykulenko
 
JVM languages "flame wars"
JVM languages "flame wars"JVM languages "flame wars"
JVM languages "flame wars"Gal Marder
 
Akka Persistence | Event Sourcing
Akka Persistence | Event SourcingAkka Persistence | Event Sourcing
Akka Persistence | Event SourcingKnoldus Inc.
 
Type-safe front-end development with Scala
Type-safe front-end development with ScalaType-safe front-end development with Scala
Type-safe front-end development with Scalatakezoe
 
Scala, Akka, and Play: An Introduction on Heroku
Scala, Akka, and Play: An Introduction on HerokuScala, Akka, and Play: An Introduction on Heroku
Scala, Akka, and Play: An Introduction on HerokuHavoc Pennington
 
Understanding Akka Streams, Back Pressure, and Asynchronous Architectures
Understanding Akka Streams, Back Pressure, and Asynchronous ArchitecturesUnderstanding Akka Streams, Back Pressure, and Asynchronous Architectures
Understanding Akka Streams, Back Pressure, and Asynchronous ArchitecturesLightbend
 
Spark real world use cases and optimizations
Spark real world use cases and optimizationsSpark real world use cases and optimizations
Spark real world use cases and optimizationsGal Marder
 
Multi-threading in the modern era: Vertx Akka and Quasar
Multi-threading in the modern era: Vertx Akka and QuasarMulti-threading in the modern era: Vertx Akka and Quasar
Multi-threading in the modern era: Vertx Akka and QuasarGal Marder
 
Scala Frameworks for Web Application 2016
Scala Frameworks for Web Application 2016Scala Frameworks for Web Application 2016
Scala Frameworks for Web Application 2016takezoe
 
Implementing Micro Services Tasks (service discovery, load balancing etc.) - ...
Implementing Micro Services Tasks (service discovery, load balancing etc.) - ...Implementing Micro Services Tasks (service discovery, load balancing etc.) - ...
Implementing Micro Services Tasks (service discovery, load balancing etc.) - ...Gal Marder
 
The Why and How of Scala at Twitter
The Why and How of Scala at TwitterThe Why and How of Scala at Twitter
The Why and How of Scala at TwitterAlex Payne
 
Node.js Enterprise Middleware
Node.js Enterprise MiddlewareNode.js Enterprise Middleware
Node.js Enterprise MiddlewareBehrad Zari
 
Dive into spark2
Dive into spark2Dive into spark2
Dive into spark2Gal Marder
 
Introduction to Apache Kafka- Part 2
Introduction to Apache Kafka- Part 2Introduction to Apache Kafka- Part 2
Introduction to Apache Kafka- Part 2Knoldus Inc.
 
What’s expected in Spring 5
What’s expected in Spring 5What’s expected in Spring 5
What’s expected in Spring 5Gal Marder
 
Introduction to akka actors with java 8
Introduction to akka actors with java 8Introduction to akka actors with java 8
Introduction to akka actors with java 8Johan Andrén
 
What’s expected in Java 9
What’s expected in Java 9What’s expected in Java 9
What’s expected in Java 9Gal Marder
 

What's hot (20)

Introduction to Scala Macros
Introduction to Scala MacrosIntroduction to Scala Macros
Introduction to Scala Macros
 
Above the clouds: introducing Akka
Above the clouds: introducing AkkaAbove the clouds: introducing Akka
Above the clouds: introducing Akka
 
Akka Actor presentation
Akka Actor presentationAkka Actor presentation
Akka Actor presentation
 
Developing distributed applications with Akka and Akka Cluster
Developing distributed applications with Akka and Akka ClusterDeveloping distributed applications with Akka and Akka Cluster
Developing distributed applications with Akka and Akka Cluster
 
JVM languages "flame wars"
JVM languages "flame wars"JVM languages "flame wars"
JVM languages "flame wars"
 
Akka Persistence | Event Sourcing
Akka Persistence | Event SourcingAkka Persistence | Event Sourcing
Akka Persistence | Event Sourcing
 
Type-safe front-end development with Scala
Type-safe front-end development with ScalaType-safe front-end development with Scala
Type-safe front-end development with Scala
 
Scala, Akka, and Play: An Introduction on Heroku
Scala, Akka, and Play: An Introduction on HerokuScala, Akka, and Play: An Introduction on Heroku
Scala, Akka, and Play: An Introduction on Heroku
 
Understanding Akka Streams, Back Pressure, and Asynchronous Architectures
Understanding Akka Streams, Back Pressure, and Asynchronous ArchitecturesUnderstanding Akka Streams, Back Pressure, and Asynchronous Architectures
Understanding Akka Streams, Back Pressure, and Asynchronous Architectures
 
Spark real world use cases and optimizations
Spark real world use cases and optimizationsSpark real world use cases and optimizations
Spark real world use cases and optimizations
 
Multi-threading in the modern era: Vertx Akka and Quasar
Multi-threading in the modern era: Vertx Akka and QuasarMulti-threading in the modern era: Vertx Akka and Quasar
Multi-threading in the modern era: Vertx Akka and Quasar
 
Scala Frameworks for Web Application 2016
Scala Frameworks for Web Application 2016Scala Frameworks for Web Application 2016
Scala Frameworks for Web Application 2016
 
Implementing Micro Services Tasks (service discovery, load balancing etc.) - ...
Implementing Micro Services Tasks (service discovery, load balancing etc.) - ...Implementing Micro Services Tasks (service discovery, load balancing etc.) - ...
Implementing Micro Services Tasks (service discovery, load balancing etc.) - ...
 
The Why and How of Scala at Twitter
The Why and How of Scala at TwitterThe Why and How of Scala at Twitter
The Why and How of Scala at Twitter
 
Node.js Enterprise Middleware
Node.js Enterprise MiddlewareNode.js Enterprise Middleware
Node.js Enterprise Middleware
 
Dive into spark2
Dive into spark2Dive into spark2
Dive into spark2
 
Introduction to Apache Kafka- Part 2
Introduction to Apache Kafka- Part 2Introduction to Apache Kafka- Part 2
Introduction to Apache Kafka- Part 2
 
What’s expected in Spring 5
What’s expected in Spring 5What’s expected in Spring 5
What’s expected in Spring 5
 
Introduction to akka actors with java 8
Introduction to akka actors with java 8Introduction to akka actors with java 8
Introduction to akka actors with java 8
 
What’s expected in Java 9
What’s expected in Java 9What’s expected in Java 9
What’s expected in Java 9
 

Similar to Lightbend Lagom: Microservices Just Right

Building a serverless company on AWS lambda and Serverless framework
Building a serverless company on AWS lambda and Serverless frameworkBuilding a serverless company on AWS lambda and Serverless framework
Building a serverless company on AWS lambda and Serverless frameworkLuciano Mammino
 
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)lennartkats
 
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-MallaKerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-MallaSpark Summit
 
Fabric - Realtime stream processing framework
Fabric - Realtime stream processing frameworkFabric - Realtime stream processing framework
Fabric - Realtime stream processing frameworkShashank Gautam
 
Intro to creating kubernetes operators
Intro to creating kubernetes operators Intro to creating kubernetes operators
Intro to creating kubernetes operators Juraj Hantak
 
Running your dockerized application(s) on AWS Elastic Container Service
Running your dockerized application(s) on AWS Elastic Container ServiceRunning your dockerized application(s) on AWS Elastic Container Service
Running your dockerized application(s) on AWS Elastic Container ServiceMarco Pas
 
Angular for Java Enterprise Developers: Oracle Code One 2018
Angular for Java Enterprise Developers: Oracle Code One 2018Angular for Java Enterprise Developers: Oracle Code One 2018
Angular for Java Enterprise Developers: Oracle Code One 2018Loiane Groner
 
Kerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit eastKerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit eastJorge Lopez-Malla
 
Apache Samza 1.0 - What's New, What's Next
Apache Samza 1.0 - What's New, What's NextApache Samza 1.0 - What's New, What's Next
Apache Samza 1.0 - What's New, What's NextPrateek Maheshwari
 
Event Sourcing - what could possibly go wrong?
Event Sourcing - what could possibly go wrong?Event Sourcing - what could possibly go wrong?
Event Sourcing - what could possibly go wrong?Andrzej Ludwikowski
 
OSCON 2014 - API Ecosystem with Scala, Scalatra, and Swagger at Netflix
OSCON 2014 - API Ecosystem with Scala, Scalatra, and Swagger at NetflixOSCON 2014 - API Ecosystem with Scala, Scalatra, and Swagger at Netflix
OSCON 2014 - API Ecosystem with Scala, Scalatra, and Swagger at NetflixManish Pandit
 
Aws Lambda in Swift - NSLondon - 3rd December 2020
Aws Lambda in Swift - NSLondon - 3rd December 2020Aws Lambda in Swift - NSLondon - 3rd December 2020
Aws Lambda in Swift - NSLondon - 3rd December 2020Andrea Scuderi
 
Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...
Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...
Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...DataStax Academy
 
Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...
Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...
Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...Anton Kirillov
 
Serverless Framework Workshop - Tyler Hendrickson, Chicago/burbs
 Serverless Framework Workshop - Tyler Hendrickson, Chicago/burbs Serverless Framework Workshop - Tyler Hendrickson, Chicago/burbs
Serverless Framework Workshop - Tyler Hendrickson, Chicago/burbsAWS Chicago
 
Building Kafka Connectors with Kotlin: A Step-by-Step Guide to Creation and D...
Building Kafka Connectors with Kotlin: A Step-by-Step Guide to Creation and D...Building Kafka Connectors with Kotlin: A Step-by-Step Guide to Creation and D...
Building Kafka Connectors with Kotlin: A Step-by-Step Guide to Creation and D...HostedbyConfluent
 
Dragoncraft Architectural Overview
Dragoncraft Architectural OverviewDragoncraft Architectural Overview
Dragoncraft Architectural Overviewjessesanford
 

Similar to Lightbend Lagom: Microservices Just Right (20)

Building a serverless company on AWS lambda and Serverless framework
Building a serverless company on AWS lambda and Serverless frameworkBuilding a serverless company on AWS lambda and Serverless framework
Building a serverless company on AWS lambda and Serverless framework
 
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
 
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-MallaKerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
 
Grails 101
Grails 101Grails 101
Grails 101
 
Revealing ALLSTOCKER
Revealing ALLSTOCKERRevealing ALLSTOCKER
Revealing ALLSTOCKER
 
Fabric - Realtime stream processing framework
Fabric - Realtime stream processing frameworkFabric - Realtime stream processing framework
Fabric - Realtime stream processing framework
 
Intro to creating kubernetes operators
Intro to creating kubernetes operators Intro to creating kubernetes operators
Intro to creating kubernetes operators
 
Running your dockerized application(s) on AWS Elastic Container Service
Running your dockerized application(s) on AWS Elastic Container ServiceRunning your dockerized application(s) on AWS Elastic Container Service
Running your dockerized application(s) on AWS Elastic Container Service
 
Angular for Java Enterprise Developers: Oracle Code One 2018
Angular for Java Enterprise Developers: Oracle Code One 2018Angular for Java Enterprise Developers: Oracle Code One 2018
Angular for Java Enterprise Developers: Oracle Code One 2018
 
Kerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit eastKerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit east
 
Apache Samza 1.0 - What's New, What's Next
Apache Samza 1.0 - What's New, What's NextApache Samza 1.0 - What's New, What's Next
Apache Samza 1.0 - What's New, What's Next
 
Event Sourcing - what could possibly go wrong?
Event Sourcing - what could possibly go wrong?Event Sourcing - what could possibly go wrong?
Event Sourcing - what could possibly go wrong?
 
OSCON 2014 - API Ecosystem with Scala, Scalatra, and Swagger at Netflix
OSCON 2014 - API Ecosystem with Scala, Scalatra, and Swagger at NetflixOSCON 2014 - API Ecosystem with Scala, Scalatra, and Swagger at Netflix
OSCON 2014 - API Ecosystem with Scala, Scalatra, and Swagger at Netflix
 
Aws Lambda in Swift - NSLondon - 3rd December 2020
Aws Lambda in Swift - NSLondon - 3rd December 2020Aws Lambda in Swift - NSLondon - 3rd December 2020
Aws Lambda in Swift - NSLondon - 3rd December 2020
 
Google Cloud Dataflow
Google Cloud DataflowGoogle Cloud Dataflow
Google Cloud Dataflow
 
Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...
Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...
Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...
 
Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...
Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...
Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...
 
Serverless Framework Workshop - Tyler Hendrickson, Chicago/burbs
 Serverless Framework Workshop - Tyler Hendrickson, Chicago/burbs Serverless Framework Workshop - Tyler Hendrickson, Chicago/burbs
Serverless Framework Workshop - Tyler Hendrickson, Chicago/burbs
 
Building Kafka Connectors with Kotlin: A Step-by-Step Guide to Creation and D...
Building Kafka Connectors with Kotlin: A Step-by-Step Guide to Creation and D...Building Kafka Connectors with Kotlin: A Step-by-Step Guide to Creation and D...
Building Kafka Connectors with Kotlin: A Step-by-Step Guide to Creation and D...
 
Dragoncraft Architectural Overview
Dragoncraft Architectural OverviewDragoncraft Architectural Overview
Dragoncraft Architectural Overview
 

More from mircodotta

Scala Past, Present & Future
Scala Past, Present & FutureScala Past, Present & Future
Scala Past, Present & Futuremircodotta
 
Akka streams scala italy2015
Akka streams scala italy2015Akka streams scala italy2015
Akka streams scala italy2015mircodotta
 
Go Reactive: Event-Driven, Scalable, Resilient & Responsive Systems (Soft-Sha...
Go Reactive: Event-Driven, Scalable, Resilient & Responsive Systems (Soft-Sha...Go Reactive: Event-Driven, Scalable, Resilient & Responsive Systems (Soft-Sha...
Go Reactive: Event-Driven, Scalable, Resilient & Responsive Systems (Soft-Sha...mircodotta
 
Effective Scala (JavaDay Riga 2013)
Effective Scala (JavaDay Riga 2013)Effective Scala (JavaDay Riga 2013)
Effective Scala (JavaDay Riga 2013)mircodotta
 
Effective Scala (SoftShake 2013)
Effective Scala (SoftShake 2013)Effective Scala (SoftShake 2013)
Effective Scala (SoftShake 2013)mircodotta
 
Scala: Simplifying Development
Scala: Simplifying DevelopmentScala: Simplifying Development
Scala: Simplifying Developmentmircodotta
 
Managing Binary Compatibility in Scala (Scala Lift Off 2011)
Managing Binary Compatibility in Scala (Scala Lift Off 2011)Managing Binary Compatibility in Scala (Scala Lift Off 2011)
Managing Binary Compatibility in Scala (Scala Lift Off 2011)mircodotta
 
Managing Binary Compatibility in Scala (Scala Days 2011)
Managing Binary Compatibility in Scala (Scala Days 2011)Managing Binary Compatibility in Scala (Scala Days 2011)
Managing Binary Compatibility in Scala (Scala Days 2011)mircodotta
 

More from mircodotta (9)

Scala Past, Present & Future
Scala Past, Present & FutureScala Past, Present & Future
Scala Past, Present & Future
 
Akka streams scala italy2015
Akka streams scala italy2015Akka streams scala italy2015
Akka streams scala italy2015
 
Akka streams
Akka streamsAkka streams
Akka streams
 
Go Reactive: Event-Driven, Scalable, Resilient & Responsive Systems (Soft-Sha...
Go Reactive: Event-Driven, Scalable, Resilient & Responsive Systems (Soft-Sha...Go Reactive: Event-Driven, Scalable, Resilient & Responsive Systems (Soft-Sha...
Go Reactive: Event-Driven, Scalable, Resilient & Responsive Systems (Soft-Sha...
 
Effective Scala (JavaDay Riga 2013)
Effective Scala (JavaDay Riga 2013)Effective Scala (JavaDay Riga 2013)
Effective Scala (JavaDay Riga 2013)
 
Effective Scala (SoftShake 2013)
Effective Scala (SoftShake 2013)Effective Scala (SoftShake 2013)
Effective Scala (SoftShake 2013)
 
Scala: Simplifying Development
Scala: Simplifying DevelopmentScala: Simplifying Development
Scala: Simplifying Development
 
Managing Binary Compatibility in Scala (Scala Lift Off 2011)
Managing Binary Compatibility in Scala (Scala Lift Off 2011)Managing Binary Compatibility in Scala (Scala Lift Off 2011)
Managing Binary Compatibility in Scala (Scala Lift Off 2011)
 
Managing Binary Compatibility in Scala (Scala Days 2011)
Managing Binary Compatibility in Scala (Scala Days 2011)Managing Binary Compatibility in Scala (Scala Days 2011)
Managing Binary Compatibility in Scala (Scala Days 2011)
 

Recently uploaded

What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....kzayra69
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commercemanigoyal112
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 

Recently uploaded (20)

What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
Advantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your BusinessAdvantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your Business
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commerce
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 

Lightbend Lagom: Microservices Just Right

  • 1. Lightbend Lagom Microservices “Just Right” Mirco Dotta @mircodotta Scala Days NYC - May 10, 2016
  • 2. Lagom - [lah-gome] Adequate, sufficient, just right
  • 3. Agenda ● Why Lagom? ● Lagom dive in ○ Development Environment ○ Service API ○ Persistence API ● Running in Production
  • 4. Why Lagom? ● Opinionated ● Developer experience matters! ○ No brittle script to run your services ○ Inter-service communication just works ○ Services are automatically reloaded on code change ● Takes you through to production deployment
  • 5. ● sbt build tool (developer experience) ● Play 2.5 ● Akka 2.4 (clustering, streams, persistence) ● Cassandra (default data store) ● Jackson (JSON serialization) ● Guice (DI) ● Architectural Concepts: immutability, Event Sourcing/CQRS, circuit breakers Under the hood
  • 7. Anatomy of a Lagom project ● sbt build ● Scala 2.11 and JDK8 ● Each service definition is split into two sbt projects: ○ api ○ Implementation
  • 9. Service definition trait HelloService extends Service { override def descriptor(): Descriptor = { named("helloservice").`with`( namedCall("/hello", sayHello _) ) } def sayHello(): ServiceCall[String, String] } // this source is placed in your api project
  • 10. ServiceCall explained ● ServiceCall can be invoked when consuming a service: ○ Request: type of incoming request message (e.g. String) ○ Response: type of outgoing response message (e.g. String) ● JSON is the default serialization format for request/response messages ● There are two kinds of request/response messages: ○ Strict ○ Streamed trait ServiceCall[Request, Response] { def invoke(request: Request): Future[Response] }
  • 11. Strict Messages Strict messages are fully buffered into memory override def descriptor(): Descriptor = { named("friendservice").`with`( pathCall("/users/:userId/friends", addFriend _) ) } def addFriend(userId: String): ServiceCall[FriendId, NotUsed]
  • 12. Streamed Messages override def descriptor(): Descriptor = { named("clock").`with`( pathCall("/tick/:interval", tick()) ) } def tick(): ServiceCall[String, Source[String, _]] ● A streamed message is of type Source (an Akka streams API) ● It allows asynchronous streaming and handling of messages ● Lagom will select transport protocol (currently WebSockets)
  • 13. Remember the Service definition? trait HelloService extends Service { override def descriptor(): Descriptor = { named("helloservice").`with`( namedCall(sayHello _) ) } def sayHello(): ServiceCall[String, String] } // this source is placed in your api project
  • 14. Here is the Service implementation class HelloServiceImpl extends HelloService { override def sayHello(): ServiceCall[String, String] { name => Future.successful(s"Hello, $name!") } } // this source is placed in your implementation project
  • 15. Inter-service communication class MyServiceImpl @Inject()(helloService: HelloService) (implicit ec: ExecutionContext) extends MyService { override def sayHelloLagom(): ServiceCall[NotUsed, String] = unused => { val response = helloService.sayHello().invoke("Lagom") response.map(answer => s"Hello service said: $answer") } }
  • 17. Principles ● Each service owns its data ○ Only the service has direct access to the DB ● We advocate the use of Event Sourcing (ES) and CQRS ○ ES: Capture all state’s changes as events ○ CQRS: separate models for write and read
  • 18. Benefits of Event Sourcing/CQRS ● Allows you to time travel ● Audit log ● Future business opportunities ● No need for ORM ● No database migration script, ever ● Performance & Scalability ● Testability & Debuggability
  • 19. Event Sourcing: Write Side ● Create your own Command and Event classes ● Subclass PersistentEntity ○ Define Command and Event handlers ○ Can be accessed from anywhere in the cluster ○ (corresponds to an Aggregate Root in DDD)
  • 20. Event Sourcing: Example Create the Command classes sealed trait FriendCommand extends Jsonable case class AddFriend(friendUserId: String) extends PersistentEntity.ReplyType[Done] with FriendCommand // more friend commands
  • 21. Event Sourcing: Example cont’d Create the Event classes sealed trait FriendEvent extends Jsonable case class FriendAdded(userId: String, friendId: String, timestamp: Instant = Instant.now()) extends FriendEvent // more friend events
  • 22. Event Sourcing: Example cont’d class FriendEntity extends PersistentEntity[FriendCommand, FriendEvent, FriendState] { def initialBehavior(snapshotState: Optional[FriendState]): Behavior = // TODO: define command and event handlers } Create a subclass of PersistentEntity
  • 23. Event Sourcing: Example cont’d val b: Behavior = newBehaviorBuilder(/*...*/) b.setCommandHandler(classOf[AddFriend], (cmd: AddFriend, ctx: CommandContext[Done]) => state.user match { case None => ctx.invalidCommand(s"User ${entityId} is not created") ctx.done() case Some(user) => ctx.thenPersist(FriendAdded(user.userId, cmd.friendUserId), (evt: FriendAdded) => ctx.reply(Done)) })
  • 24. b.setEventHandler(classOf[FriendAdded], (evt: FriendAdded) => state.addFriend(evt.friendId)) Event Sourcing: Example cont’d No side-effects in the event handler!
  • 25. Event Sourcing: Example cont’d Create the State class case class FriendState(user: Option[User]) extends Jsonable { def addFriend(friendUserId: String): FriendState = user match { case None => throw new IllegalStateException( "friend can't be added before user is created") case Some(user) => val newFriends = user.friends :+ friendUserId FriendState(Some(user.copy(friends = newFriends))) } }
  • 26. class FriendServiceImpl @Inject() (persistentEntities: PersistentEntityRegistry) (implicit ec: ExecutionContext) extends FriendService { // at service startup we must register the needed entities persistentEntities.register(classOf[FriendEntity]) def addFriend(userId: String): ServiceCall[FriendId, NotUsed] = request => { val ref = persistentEntities.refFor(classOf[FriendEntity], userId) ref.ask[Done, AddFriend](AddFriend(request.friendId)) } // ... } Event Sourcing: Example cont’d
  • 27. Event Sourcing: Read Side ● Tightly integrated with Cassandra ● Create the query tables: ○ Subclass CassandraReadSideProcessor ○ Consumes events produced by the PersistentEntity and updates tables in Cassandra optimized for queries ● Retrieving data: Cassandra Query Language ○ e.g., SELECT id, title FROM postsummary
  • 28. Running in Production ● sbt-native packager is used to produce zip, MSI, RPM, Docker ● Lightbend ConductR* (our container orchestration tool) ● Lightbend Reactive Platform* ○ Split Brain Resolver (for Akka cluster) ○ Lightbend Monitoring *Requires a Lightbend subscription (ConductR is free to use during development)
  • 29. Current[Lagom] ● Current version is 1.0.0-M2 ○ 1.0 soon ● Java API, but no Scala API yet ○ We are working on the Scala API ○ But using Scala with the Java API works well! https: //github.com/dotta/activator-lagom-scala-chirper
  • 30. Future[Lagom] ● Maven support ● Message broker integration ● Scala API ● Support for other cluster orchestration tools ● Support for writing integration tests ● Swagger integration ○ Which also removes binary coupling!
  • 31. Next: Seq[Step] ● Try Lagom yourself ○ https://lightbend.com/lagom ● Using Scala with Lagom ○ https://github.com/dotta/activator-lagom-scala-chirper ● Lagom on Github ○ https://github.com/lagom/lagom ● Read Jonas Bonér's free book Reactive Services Architecture ○ https://lightbend.com/reactive-microservices-architecture ● Great presentation by Greg Young on why you should use ES ○ https://www.youtube.com/watch?v=JHGkaShoyNs
  • 32. Thank you for listening! @mircodotta @lagom
  • 33. override def descriptor(): Descriptor = { named("friendservice").`with`( namedCall("/users", createUser _), pathCall("/users/:id", getUser _), restCall(Method.POST, "/users/:userId/friends", addFriend _) ) } def createUser(): ServiceCall[User, NotUsed] def getUser(id: String): ServiceCall[NotUsed, User] def addFriend(userId: String): ServiceCall[FriendId, NotUsed] Different kinds of service call descriptors