During this session we will explore the component and the best practices behind a scalable Scala-based microservice architecture. We will see how to build a REST service with Akka and Spray, how to document its API with Swagger, how to package it with Sbt and Docker, how to deploy it with Mesos and Marathon and how to let him interact with other services with Bamboo. The talk with be full of code and practical tips.
2. WHO IS THIS GUY?
20 years ago C / C++ / x86 ASM
15 years ago C / C++ / Perl / PHP
10 years ago Ruby / Perl / JS / Java
last 5 years Scala / Ruby / JS / LUA
FoundedWorkedatTechnologies
7. BUSINESS LOGIC = AKKA ACTORS
Sum
Service
HTTP
API
SumOp
SumRes
“ask” pattern
8. BUSINESS LOGIC = AKKA ACTORS
object SumService {
def props = Props(classOf[SumService])
!
case class SumOp(a: Int, b: Int)
case class SumRes(result: Int)
}
!
class SumService extends Actor {
import SumService._
!
def receive: Receive = {
case SumOp(a, b) => sender() ! SumRes(a + b)
}
}
9. REST API = SPRAY.IO
Sum
Service
SPRAY
API
SumOp
SumRes
GET /v1/sum
JSON
10. REST API = SPRAY.IO
case class SumApiResponse(result: Int)
!
object SumProtocol extends DefaultJsonProtocol {
implicit val sumApiResponseFormat = jsonFormat1(SumApiResponse)
}
!
class SumHttpServiceV1(services: Services) {
import SumProtocol._
!
def route = path("v1" / "sum") {
get {
parameters('a.as[Int], 'b.as[Int]) { (a, b) =>
def future = (services.sumService ? SumOp(a, b)).mapTo[SumRes]
onSuccess(future) { response =>
complete(SumApiResponse(response.result))
}
}
}
}
}
11. API DOCS = SWAGGER
SPRAY-
SWAGGER
GET /
HTML/JSON
docs
12. API DOCS = SWAGGER
@Api(value = “/v1/sum", description = "Sum numbers.")
class SumHttpServiceV1(services: Services) {
…
}
14. API DOCS = SWAGGER
@ApiModel(description = "Result of the sum")
case class SumApiResponse(
@(ApiModelProperty @field)(value = "The sum of a and b")
result: Int
)
20. CONFIG = TYPESAFE CONFIG
val config = ConfigFactory.defaultApplication()
$ sbt -Dconfig.resource=development.conf run
Loads application.conf by default
Loads development.conf
21. CONFIG = TYPESAFE CONFIG
{
mysql_username=${MYSQL_USERNAME}
mysql_password=${MYSQL_PASSWORD}
}
PRO-TIP
Don’t store passwords with source code!
Instead make use ENV vars substitution and
keep passwords in a safe place.
22. HEALTH = SPRAY + HAPROXY
SPRAY
GET /ping
Load
Balancer
Are you ok?
23. HEALTH = SPRAY + HAPROXY
def route = get {
path("ping") {
complete("pong")
}
}