Decoupling with Lerna Monorepos, Yeoman, and a Microservice Architecture

It was December, 2019 and we were ready to launch a brand new product, issued by our parent company, MassMutual, called: AgeUp. We had wrapped up the last of our 2019 engineering goals and began making our roadmap for 2020. When we took the time to assess the minimum viable product (MVP) we had built through the lens of getting where we wanted to be in a year’s time, the feelings were mixed. We were attached; it was the spunky, little “app-that-could” which we built up to prod-stable in a very short time. However, there were flaws with our creation. The build times were too high and trending in the wrong direction at a concerning rate. The client-side orchestration was unwieldy. There were complications around expanding styling in a way that was manageable for engineers without being restrictive to design. In general, it was a mini-lith; with all the potential of a monolith if given the time to grow.

We realized what we had built was too tightly coupled and the fit was not going to work. Still, at its core, all these valuable pieces were just sitting there…

  • Integrations with Auth0 for user management and two-factor
  • Integrations with DocuSign for e-signature of documents
  • A logging and monitoring system backed by Splunk
  • PDF document generation functionality with Puppeteer

This was a big problem because the products we planned to build in the future, including a disability insurance (DI) product issued by MassMutual, needed to use these services too. But because they were so tightly coupled with AgeUp, trying to use them with a new product would become unsustainable and expensive very quickly. We were going to need to do something else. It was time to get creative.

Orchestrating microservices with a Lerna Monorepo

We decided to use a Lerna monorepo to house everything we were going to need: an ever-growing suite of fully-decoupled microservices, multiple product clients, highly-testable best-practices across the stack, and a home for automation.

Lerna helps orchestrate the running of local instances down to simple commands and manages versioning. Since the code is in a monorepo, there are no concerns around managing multiple repositories for a single feature. The local development environment has high-parity to the deployed environments, allowing for more confidence and fewer moving parts as code elevates to production. The possibilities of how our work could scale in this new ecosystem seemed endless. We named our little project “World-Turtle”, and decided it could lead us to where we wanted to go.

Implementing Lerna

The early plan was clear enough, and since development of the new DI product was not slated to begin until June, we had the time to implement it. We would make each microservice an Express server. These servers could be deployed to the same Kubernetes cluster where they would live on the same private network. With each service in its own scalable deployment, they are able to reference each other the same way across all environments. The business logic for the first few microservices which needed to be built could be lifted from the AgeUp MVP server. We got to work.

Near the beginning of the project, the AgeUp squad started work on a new demographic: the Buy For Self customer. Whereas our original AgeUp product was intended for the children of older parents to buy the product, the Buy For Self customer was the older parents themselves. With a fancy new design in-hand and a lot of styling complications back in the MVP code, it was decided a new React client would be started in World-Turtle as well. Our ever growing ecosystem was going to give us the room to build a new way to do client applications with better flexibility around design and improved state management. This was an additional piece that could help the DI work which had not been planned previously.

The early plan worked… well… according to plan. A short time in to the development of World-Turtle, we’d built:

  • lunar-logger: A logging microservice useable by both microservices and public clients; logs are stored in a Splunk instance
  • planet-koi: The new React client for AgeUp
  • space-rover: A microservice for Auth0 interactions
  • koala-moon: A publicly accessible gateway server for clients to interact with microservices
  • koala-moon-joey: A utility to make it cleaner for clients to interact with koala-moon
  • uni-kitten: A library of reusable React components allowing us fully flexible styling

Decoupling allowed us to take on even more new products

It was now June, 2020: We adapted to a new life in the pandemic. Stragglers to team meetings having to stand against the wall in crowded conference rooms for a lack of chairs seemed like a distant past. We started a new claims project; the newly formed squad named themselves after the superhero mantra of “The Incredibles”.

Each project is going to be adding unique pieces, many of which will be shareable, even if not immediately shared by multiple projects. With so much activity on the precipice of coming-to-be in this ecosystem there was an evolutionary leap… Yeoman. This newfound technology allowed us to make a generator for World-Turtle microservices. We would not need to take an existing microservice and copy it for expansion; hoping all the correct points were adjusted in the correct ways. Instead we would run one command which would generate a new microservice fully configured to work in the World-Turtle ecosystem. Just add endpoints and business logic needed for the new microservice. With this addition, the velocity of our teams was going to skyrocket.

Over the coming months, with 3 teams actively working on their projects the offerings of World-Turtle expanded rapidly. By the end of Q3, World-Turtle had expanded, adding…

  • claim-eleon: A React client for claimants in the Claims project
  • homing-pigeon: A microservice for interacting with Google APIs for location information
  • extragalactic-ox: A React client for DI
  • cosmic-crab: A microservice for interacting the the Underwriting system
  • star-grazer: A microservice to contain the business logic for the Claims project
  • the-den: A microservice to contain the business logic for the DI project and handles GraphQL connections for extraterrestrial-axolotl
  • constellation-station: A microservice for integrating with DocuSign to e-sign documents
  • snail-mail: A microservice for integrating with Mandrill to send emails
  • rastro: A microservice for integrating with Chase PaymentTech to process credit card payments
  • star-chart: A microservice backed by Puppeteer to generate PDFs from HTML

… to the lineup of packages living in the World-Turtle ecosystem. Many of which are reusable. Meaning, the next time we need to spin up a project, all of these pieces will just be there waiting to be consumed by a new set of business logic for a new project.

The Past’s Future is Now

It was December, 2020. AgeUp released in 3 new states. The claims work went to production and helped someone over the holidays. The work for DI is completed and launched. We stand, once more, with our goals behind us and the future before. We have many things we want to do and we now have confidence that our tech stack will be able to grow and adapt to whatever projects head our way.

AgeUp is a Deferred Income Annuity (ICC19DTCDIA) issued by Massachusetts Mutual Life Insurance Company (MassMutual), Springfield, MA 01111 and offered exclusively through Haven Life Insurance Agency, LLC. Contract and rider form numbers and features may vary by state and may not be available in all states.

Haven Disability is a Short Term Disability Insurance Policy (ICC20-HLSTDI-POL) issued by Massachusetts Mutual Life Insurance Company (MassMutual), Springfield, MA 01111–0001 and offered exclusively through Haven Life Insurance Agency, LLC. Policy and rider form numbers and features may vary by state and may not be available in all states. Our Agency license number in Arkansas is 100139527.

--

--