andrea lattuada, gabriele petronella - building startups on scala

62
BUILDING STARTUPS ON SCALA TURN IDEAS INTO REALITY

Upload: scala-italy

Post on 12-Aug-2015

49 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

B U I L D I N G S TA R T U P S O N S C A L A

T U R N I D E A S I N T O R E A L I T Y

Page 2: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

W H O A R E Y O U ?

buildo, a young italian company

we help startups everywhere execute on their vision

Page 3: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

SUSTAINABILITY FAIRNESS QUALITY

O U R P I L L A R S

Page 4: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

L E T ’ S TA K E A S T E P B A C K

Page 5: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

A L O N G T I M E A G O I N A G A L A X Y FA R FA R AWAY

• a wild scary large project appears!

Page 6: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

F L A S H B A C K : N O T L O N G B E F O R E

• Intern at Google, MongoDB

• Freelancer

• C++

• Python (programming is fun again)

• Java (university)

• Haskell

• Scala

Page 7: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

F L A S H B A C K : N O T L O N G B E F O R E

• Startupper and freelance dev

• Java (university)

• Objective-C <3

• “blocks? That’s confusing…”

• intrigued by Haskell

• Scala (Martin’s online course)

Page 8: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

T H E R E S T O F T H E ( I N I T I A L ) C R E W

Page 9: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

R E C E N T LY B U R N E D B Y …

• a new startup, for hosting and serving videos

• a year of work

• countless refactors

• …node.js

Page 10: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

B A C K T O O U R S C A R Y P R O J E C T

• we wanted

• type safety

• expressiveness

• flexibility

Page 11: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

FA S T- F O R WA R D T O T O D AY

Page 12: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

B U I L D O , T O D AY

• startups, in scala?!

• everybody knows rails/node/php is the hipster startup language!

• waxed mustache for extra points

Page 13: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

S TA R T U P T E C H N O L O G I E S

07/08/2014 - source: http://codingvc.com/which-technologies-do-startups-use-an-exploration-of-angellist-data

Page 14: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

P E R C E P T I O N

• “Do you know Scala?”

• “Isn’t it that thing Twitter uses?”

Page 15: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

P E R C E P T I O N ( C O N T ’ D )

• “developing in scala is slow”

• “the learning curve is steep”

• “is it worth it for a startup?”

Page 16: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

S C A L I N G S C A L A D O W N

• we started with a large project

• and applied what we learned to startups

Page 17: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

W H Y ?

• well, we liked it :-)

• small team

• the final S in “startups” is not silent

Page 18: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

O K , W H Y D O Y O U L I K E I T ?

• it takes more time to ship code • it takes less time to ship code that works

Page 19: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

O K , W H Y D O Y O U L I K E I T ? ( C O N T ’ D )

• intrinsic correctness and clarity • easy to write testable code • refactor with confidence • JVM is nice

Page 20: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

behind the scenes

Page 21: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

H O W D O W E D O T H I S ?

1. dealing with a diverse and evolving set of requirements

2. akka 3. controllers 4. open problems

Page 22: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

1 . D E A L I N G W I T H A D I V E R S E S E T O F R E Q U I R E M E N T S

Page 23: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

M I X - M AT C H I N F R A S T R U C T U R E

Page 24: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

spray akka slick elasticsearch

Page 25: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

spray akka slickearly stage start-up,simple requirements

Page 26: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

spray akka slick

innovation,evolved requirements

Page 27: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

complex system

spray akka slick elasticsearch

Page 28: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

spray akka slick elasticsearch

Page 29: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

C A K E PAT T E R N

Page 30: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

C A K E PAT T E R N

Page 31: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

C A K E PAT T E R N

Page 32: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

C A K E PAT T E R N

Page 33: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

cake pattern

trait UserService extends DataModule { trait UserServiceDef { def login(username: String, password: String): Option[Token] }

def userService: UserServiceDef }

Page 34: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

cake pattern

trait UserService extends DataModule { trait UserServiceDef { def login(username: String, password: String): Option[Token] }

def userService: UserServiceDef }

trait DataModule { type Token

trait DataModuleDef { def getUserByName(username: String): Option[User] def storeToken(user: User, token: Token): Boolean }

def dataModule: DataModuleDef }

Page 35: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

trait MemoryDataModule { self: DataModule => type Token = String

object dataModule extends DataModuleDef { val users = new scala.collection.mutable.Map[String, User] val tokens = new scala.collection.mutable.Map[User, Token] def getUserByName(username: String): Option[User] = users.get(username) def storeToken(user: String, token: Token): Boolean = tokens += user -> token } }

trait DataModule { type Token

trait DataModuleDef { def getUserByName(username: String): Option[User] def storeToken(user: User, token: Token): Boolean }

def dataModule: DataModuleDef }

Page 36: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

trait MemoryDataModule { self: DataModule => … }

trait AppUserService { self: UserService => … }

object app extends MemoryDataModule with AppUserService

println(app.login("utaal", "secretpassword"))

Page 37: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

router

controller

mysql mongodb

Page 38: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

F R A M E W O R K S

Page 39: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

N O , T H A N K S github.com/buildo/ingredients

Page 40: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

// POST /consultation/15/confirm

(post & path(“consultations” / IntNumber / “confirm”)) { consultationId =>

complete(confirmConsultation(consultationId))

} ~

typesafe router

Page 41: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

• cake pattern • tests • type safety

1 . D E A L I N G W I T H A D I V E R S E S E T O F R E Q U I R E M E N T S

Page 42: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

2 . A K K A

Page 43: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

A S Y N C

reactive apps, don’t block a thread per request

Page 44: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

A K K A

akka tell “!” is awkward with request-response akka ask “?” gets you Futures that are not bound to an Actor just use Futures

Page 45: Andrea Lattuada, Gabriele Petronella - Building startups on Scala
Page 46: Andrea Lattuada, Gabriele Petronella - Building startups on Scala
Page 47: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

• use akka for dispatching requests(in spray)

• Futures for business logic • Akka for async tasks

(notifications, elasticsearch updates)

2 . A K K A

Page 48: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

3 . C O N T R O L L E R S

Page 49: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

typesafe router

trait ConsultationControllerDef {

def confirmConsultation(consultationId: Int):

Future[ControllerResponse[Unit]]

}

// POST /consultation/15/confirm

(post & path(“consultations” / IntNumber / “confirm”)) { consultationId =>

complete(

(confirmConsultation(consultationId))

: Future[ControllerResponse[Unit]]

)

} ~

Page 50: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

sealed trait ControllerResponse[+T]

object ControllerResponse { sealed trait ControllerError

case object NotFound extends ControllerError case class InvalidOperation(desc: String) extends ControllerError case class Forbidden(desc: String) extends ControllerError … … …

case class Ok[T](value: T) extends ControllerResponse[T] case class UserError(err: ControllerError) extends ControllerResponse[Nothing] }

response semantics

Page 51: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

def confirmConsultation(consultationId: Int, user: User): Future[ControllerResponse[Unit]] =

checkConsultationData.updateStatus( consultationId, ConsultationStatus.Confirmed) map ( throwOnUnmatched { case DataActionResult.Ok(_) => OkEmpty })

controller workflow

Page 52: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

def confirmConsultation(consultationId: Int, user: User): Future[ControllerResponse[Unit]] =

checkRole(user, UserRole.Patient) { checkConsultationExists(consultationId) { c => checkConsultationOwner(c, user) { checkConsultationPending(c) { checkConsultationData.updateStatus( consultationId, ConsultationStatus.Confirmed) map ( throwOnUnmatched { case DataActionResult.Ok(_) => OkEmpty }) } } } }

controller workflow

CALLBACK HELL

Page 53: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

monadic controllers

type CtrlFlow[A] = \/[CtrlError, A]

sealed trait CtrlError

object CtrlError { case class InvalidOperation(desc: String) extends CtrlError case class Forbidden(desc: String) extends CtrlError case object NotFound extends CtrlError … … … }

Page 54: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

def confirmConsultation(consultationId: Int, user: User): FutureCtrlFlow[Unit] = for { _ <- eitherT(checkRole(user, UserRole.Patient).point[Future]) c <- checkConsultationExists(consultationId) _ <- eitherT(checkConsultationOwner(c, user).point[Future]) _ <- eitherT(checkConsultationPending(c).point[Future]) res <- eitherT(checkConsultationData.updateStatus(consultationId, ConsultationStatus.Confirmed).map(_.point[CtrlFlow])) } yield { throwIfNotOk(res) Ok(()) }

monadic controllers

type FutureCtrlFlow[B] = EitherT[Future, CtrlError, B]

Page 55: Andrea Lattuada, Gabriele Petronella - Building startups on Scala
Page 56: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

• monad! • non-trivial to design,

straightforward to use

3 . C O M P L E X C O N T R O L L E R L O G I C

Page 57: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

4 . O P E N P R O B L E M S

Page 58: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

M O D U L A R I T Y

• modularity comes with a cost • boilerplate to translate between internal and

external representations • we can’t trace a request across different

layers

Page 59: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

P E O P L E

• you can’t throw developers at this • you need good programmers • scala is (still) a good hiring signal

Page 60: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

Good programmers are up to 30 times better than mediocre programmers, according to “individual differences” research. Given that their pay is never commensurate, they are the biggest bargains in the software field.

Robert L. Glass

Page 61: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

@milanoscala

Page 62: Andrea Lattuada, Gabriele Petronella - Building startups on Scala

Thank you