Refactoring Monoliths to Microservices with Functional Programming

James Ward | @_JamesWard
Platform Evangelist @ Salesforce.com

Monoliths

A single block or piece of stone of considerable size

Microservices

Microservices are the components of a monolithic system decoupled by TCP/IP.

Conway's Law

organizations which design systems ... are constrained to produce designs which are copies of the communication structures of these organizations

Decouple: Teams & Deployment & Operations

Functional Programming

  • Programming with functions
  • Immutable / No side-effects (Pure Functions)
  • Functions can take & return functions (Higher-Order Functions)

Imperative Functional
int[] ints = {1, 2, 3};
for (int i = 0; i < ints.length; i++) {
  ints[i]++;
}
val addOne = { n: Int => n + 1 }

val ns = Seq(1,2,3)
val newNs = ns.map(addOne)

FP in Play Framework

val helloWorld = { request: Request[AnyContent] =>
  Ok("hello, world")
}

val index = Action(helloWorld)
case class Bar(name: String)

val barWrites = Json.writes[Bar]

val bar = Action {
  val myBar = Bar("my bar")
  Ok(Json.toJson(myBar)(barWrites))
}

Requirements for Refactoring to a Microservice

  • The piece of functionality does NOT have shared mutable state
  • AND

    • The piece of functionality has independent operational or computational needs
    • OR

    • The piece of functionality has cross-platform clients

Why is mutability so bad?

Spot the mutation:

List<Foo> foos = dbService.getFoos();
doSomething(foos);
calcSomething(foos);
foos = updateFoos(foos);
You can't mutate memory over a network boundary.

Immutability Defines Clear & Linear Mutation Boundaries

val foos = dbService.getFoos()
val newFoos = updateFoos(foos)

Refactoring to a Microservice

val bar = Action.async {
  wsClient.url("http://localhost:8000/bar").get().map { response =>
    Ok(response.json)
  }
}

How to Get There

  • Tests!
  • Go Immutable
  • Shared Libraries?
  • Lowest Hanging Fruit First
  • Bonus Points for Non-Blocking

It's Not All Rainbows and Ponies

  • Service Discovery
  • Cache Locality
  • Quality & Compliance
  • Service Versioning
  • Dev Experience

Questions?


Reach out: @_JamesWard