Engineering

Why We Write Micro-Services in Kotlin

Spruce News
Alex Zuzin
March 5, 2019

Spruce is a title agency. Our platform enables fast, frictionless, and transparent real estate transactions across the country. We believe the future of real estate will be driven by automation and empowering homeowners, so our mission is to make real estate transactions amazing for everyone involved in the process.

When you buy or refinance a house, we’re the ones doing the paperwork and moving the money. If you’ve dealt with a title agency before, you may have found the experience surprisingly expensive and rather confounding. We’re working to change all that with software (and hiring engineers to build it).

We bootstrapped with Rails, but the nature of the domain — the insides of a title agency are a cross between a law firm and a bank — lent itself nicely to microservices, so we went shopping for the next platform. The strong preference was for the JVM — unrivaled at runtime maturity and the size and quality of the library ecosphere — but for the fact that its language options have always left a lot to be desired.

To consider just the most widely used ones, Java 11 with Spring Boot is a far cry from the much-maligned Java 5 with J2EE, yet the language is coming up on a quarter century and looks it. Scala is huge and demanding — anything non-trivial requires facility with monads, type-level concepts and Scala’s type inference limitations hobbling both. It’s also famously slow to code in. And Clojure is, of course, a LISP. Solid arguments have been made that its efficiencies pay for the learning curve (and there are fans on the team), but in the end writing code to generate legal paperwork and keep escrow accounts in a language without a static type checker was not considered a viable option. Enter Kotlin.

Designed by JetBrains to replace Java as the language of the IDEA platform, it’s solidly up-to-date without being unduly experimental, flawlessly interoperates with Java, and has excellent IDE support (which, given its provenance, you would expect). Its block syntax allows type-safe DSLs (domain-specific languages), and the early availability of an Android UI DSL has led to Kotlin becoming the de facto standard for new Android development. Yet it’s not limited to mobile — it can go anywhere Java can go, and several companies have been pioneering its use for back-end development. For almost two years now, Spruce has been a highly satisfied early adopter.

Kotlin checks off a solid set of basic features one expects from a statically typed language in 2019:

  • lambdas
  • proper higher-kinded types with type inference
  • preferred immutability
  • inline constructor syntax
  • null-safety
  • a solid if uninspired pattern matching with exhaustiveness checks
  • ADTs (algebraic data types), and
  • a suitable runtime library incorporating all of the above

It’s also self-consciously un-pure functional — there are, by design, neither monadic comprehensions nor type classes. But there are several excellent bonus features:

Here’s a utility extension function we frequently use to parse JSON with Jackson, also demonstrating the use of block syntax and reified types:

val mapper = ObjectMapper().apply {
  registerModule(KotlinModule())
}
inline fun <reified E> String.fromJson(): E =
  mapper.readValue<E>(this, object : TypeReference<E>() {})

And its usage:

val anObject: Map<String, Any> = “””{“what”: “that”}”””.fromJson()

Note that if the compiler can infer the type of the resulting value, you don’t need to specify the type argument to the function. The triple quotes are Kotlin’s raw string notation.

Kotlin's few gotchas so far included:

  • the potential to confuse receiver arguments in nested blocks/lambdas (alleviated by the use of the somewhat wordy this@ syntax)
  • the occassional type inference blip requiring an explicit cast
  • comparative, if tolerable, instability of the APIs. E.g. the upgrade from 1.2 to 1.3 changed the implementation details of reflection, quietly breaking JSON parsing with confusing error messages about missing classes

If your team should like to adopt Kotlin, having a team member with Java expertise will significantly smooth the ride.

We write our Kotlin micro-services using the excellent “server-as-a-function” framework http4k, to which we also contribute, publish them in Docker containers and deploy on Google Kubernetes Engine in an Istio service mesh. If any of this, or fixing the US home buying process, sounds like something you might want to be a part of, then as mentioned before, we are hiring.

List Example
A simple short Subheading goes in here
  • Sed ut perspiciatis unde omnis iste natus error.
  • Quia voluptas sit aspernatur aut odit aut fugit.
  • Inventore veritatis et quasi architecto.
A simple short Subheading goes in here
  • Sed ut perspiciatis unde omnis iste natus error.
  • Quia voluptas sit aspernatur aut odit aut fugit.
  • Inventore veritatis et quasi architecto.
Richtext with Image
A simple short Subheading goes in here

Sed ut perspiciatis unde omnis iste natus error sit vol uptatem accusantium doloremque laudantium, total merem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae nugit

Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.

Sed ut perspiciatis unde omnis iste natus error sit vol uptatem accusantium doloremque laudantium, total merem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae nugit

Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.

Article by
Alex Zuzin

Why We Write Micro-Services in Kotlin

Spruce is a title agency. Our platform enables fast, frictionless, and transparent real estate transactions across the country. We believe the future of real estate will be driven by automation and empowering homeowners, so our mission is to make real estate transactions amazing for everyone involved in the process.

When you buy or refinance a house, we’re the ones doing the paperwork and moving the money. If you’ve dealt with a title agency before, you may have found the experience surprisingly expensive and rather confounding. We’re working to change all that with software (and hiring engineers to build it).

We bootstrapped with Rails, but the nature of the domain — the insides of a title agency are a cross between a law firm and a bank — lent itself nicely to microservices, so we went shopping for the next platform. The strong preference was for the JVM — unrivaled at runtime maturity and the size and quality of the library ecosphere — but for the fact that its language options have always left a lot to be desired.

To consider just the most widely used ones, Java 11 with Spring Boot is a far cry from the much-maligned Java 5 with J2EE, yet the language is coming up on a quarter century and looks it. Scala is huge and demanding — anything non-trivial requires facility with monads, type-level concepts and Scala’s type inference limitations hobbling both. It’s also famously slow to code in. And Clojure is, of course, a LISP. Solid arguments have been made that its efficiencies pay for the learning curve (and there are fans on the team), but in the end writing code to generate legal paperwork and keep escrow accounts in a language without a static type checker was not considered a viable option. Enter Kotlin.

Designed by JetBrains to replace Java as the language of the IDEA platform, it’s solidly up-to-date without being unduly experimental, flawlessly interoperates with Java, and has excellent IDE support (which, given its provenance, you would expect). Its block syntax allows type-safe DSLs (domain-specific languages), and the early availability of an Android UI DSL has led to Kotlin becoming the de facto standard for new Android development. Yet it’s not limited to mobile — it can go anywhere Java can go, and several companies have been pioneering its use for back-end development. For almost two years now, Spruce has been a highly satisfied early adopter.

Kotlin checks off a solid set of basic features one expects from a statically typed language in 2019:

  • lambdas
  • proper higher-kinded types with type inference
  • preferred immutability
  • inline constructor syntax
  • null-safety
  • a solid if uninspired pattern matching with exhaustiveness checks
  • ADTs (algebraic data types), and
  • a suitable runtime library incorporating all of the above

It’s also self-consciously un-pure functional — there are, by design, neither monadic comprehensions nor type classes. But there are several excellent bonus features:

Here’s a utility extension function we frequently use to parse JSON with Jackson, also demonstrating the use of block syntax and reified types:

val mapper = ObjectMapper().apply {
  registerModule(KotlinModule())
}
inline fun <reified E> String.fromJson(): E =
  mapper.readValue<E>(this, object : TypeReference<E>() {})

And its usage:

val anObject: Map<String, Any> = “””{“what”: “that”}”””.fromJson()

Note that if the compiler can infer the type of the resulting value, you don’t need to specify the type argument to the function. The triple quotes are Kotlin’s raw string notation.

Kotlin's few gotchas so far included:

  • the potential to confuse receiver arguments in nested blocks/lambdas (alleviated by the use of the somewhat wordy this@ syntax)
  • the occassional type inference blip requiring an explicit cast
  • comparative, if tolerable, instability of the APIs. E.g. the upgrade from 1.2 to 1.3 changed the implementation details of reflection, quietly breaking JSON parsing with confusing error messages about missing classes

If your team should like to adopt Kotlin, having a team member with Java expertise will significantly smooth the ride.

We write our Kotlin micro-services using the excellent “server-as-a-function” framework http4k, to which we also contribute, publish them in Docker containers and deploy on Google Kubernetes Engine in an Istio service mesh. If any of this, or fixing the US home buying process, sounds like something you might want to be a part of, then as mentioned before, we are hiring.