Glenn Engstrand

Have you ever been involved in a microservice rewrite effort? Come with me as I take you through a Scala microservice coding adventure that was a complete rewrite of an existing Scala microservice. We shifted paradigms in the hope of making Scala more desirable. Was the new service a real improvement over the old one? Let’s find out.

Questions and Answers

In the peer review process for the document below, people have asked these questions.

Q: Why did you pick Doobie over Slick? Isn't Slick more popular than Doobie?
A: Slick is reactive only. There are no synchronous APIs. Since this microservice is synchronous, it makes more sense to use Doobie which provides both synchronous and asynchronous APIs. In order to use Slick, I would have had to write code that awaits for Slick's futures which are wrapping synchronous JDBC calls.
Q: Are you saying that Scalatra is faster than Finatra?
A: No. I am saying that Scalatra is more efficient than Finatra for RESTful (i.e. synchronous) APIs and that Finatra is more efficient than Scalatra for reactive (i.e. asynchronous) APIs.
Q: Why did you add the Swagger integration?
A: I originally created feed2 right before Swagger really took off so I didn't include it back then. All of the microservices developed since feed2 do include Swagger. I include it because it is a really successful MDSD that does a good job of accelerating your time to value.
Q: What is Garbage Collection pressure?
A: If a Java application creates a lot of objects that fall out of scope, then the application must reclaim the memory used by those objects. Otherwise the application would just run out of memory. That reclaimation is a process called Garbage Collection. Sometimes all application threads have to be stopped while the garbage collector moves objects around in order to defragment the memory that is still being used. This puts pressure on the application since it looks like it is running but it is not actually doing anything relevant to the desired functionality of the application itself.
Q: In the past, you always used EC2 so why did you run the tests on GKE?
A: Because it is super easy to set up. Scroll near the bottom of this wiki topic where it says Google Kubernetes Engine to see what I did to run this. Compare that to what I have to do in order to run the same tests on AWS.
Q: What is the "dreaded diamond" problem?
A: The term comes from C++ where multiple inheritance is supported. Consider the following class inheritance hierarchy. Class A has two subclasses, B and C. Class D inherits from both B and C. If a method is called on D that is defined on A and overriden in both B and C, then which implementation gets run? It could be either B or C. That non-determinism is the problem.
Q: Why go to the bother of type classes for Dependency Injection? Couldn't you have simply injected the dependencies as parameters in the constructors of the classes that depend on them?
A: That would have worked for this news feed microservice due to its simplicity. Real world, business oriented microservices have circular dependencies. Constructor based DI won't work with circular dependencies but type classes will. It is possible to refactor your classes in order to remove the circular dependencies but then your classes won't be domain driven anymore. Such a refactor would decrease the readability of the code.

References

Here are the additional sources referenced in the document below.

reference description
sample news feed written in scala From this folder, you can build the feed2 project which is what the document below is referencing as the legacy system.
Another News Feed Microservice in Scala From this folder, you can build the feed6 project which is what the document below is referencing as the rewrite.
Finatra Finatra is a Scala services framework built on top of TwitterServer and Finagle.
Netty Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.
Cake Pattern The Cake pattern can be (loosly) considered as Scalas answer to Dependency Injection. The basic application of DI and the Cake pattern solve the same thing: dependencies between components.
Scalatra Scalatra is a simple, accessible and free web micro-framework. It combines the power of the JVM with the beauty and brevity of Scala, helping you quickly build high-performance web sites and APIs.
Jetty Eclipse Jetty provides a Web server and javax.servlet container, plus support for HTTP/2, WebSocket, OSGi, JMX, JNDI, JAAS and many other integrations. These components are open source and available for commercial use and distribution.
Type Classes Type classes were originally developed in Haskell as a disciplined alternative to ad-hoc polymorphism. Type classes have been shown to provide a type-safe solution to important challenges in software engineering and programming languages such as, for example, retroactive extension of programs. They are also recognized as a good mechanism for concept-based generic programming and, more recently, have evolved into a mechanism for type-level computation.
Swagger Swagger is the world’s largest framework of API developer tools for the OpenAPI Specification(OAS), enabling development across the entire API lifecycle, from design and documentation, to test and deployment.
Doobie Doobie is a pure functional JDBC layer for Scala and Cats. It is not an ORM, nor is it a relational algebra; it simply provides a principled way to construct programs (and higher-level libraries) that use JDBC.
ElasticSearch client The official high-level client for Elasticsearch. Based on the low-level client, it exposes API specific methods and takes care of requests marshalling and responses un-marshalling.

Revisiting Scala