Site icon Rightmove Tech Blog

Monolith to microservice – how we rebuilt a legacy frontend

AI-generated two panel cartoon image. On the left hand side, some engineers are frustrated with legacy code. On the right hand side, the same engineers are celebrating their cleaner codebase. I don't know where the third engineer has gone 😃

It’s an inescapable fact that any technology company will eventually have to deal with legacy code.

Systems naturally age over time, and often become more difficult to change or understand. They may have business logic becoming tangled with implementation details in a sprawling monolithic codebase, or may become stuck on older versions of languages or frameworks. Sometimes we can live with the risks for internal-only tools, but what about for external, revenue-generating applications? 

In this post I’ll share my team’s decommissioning journey and how we rebuilt a legacy frontend as a modern microservice. If you’re reading this and currently involved with a decommissioning effort yourself, hopefully parts of this journey will resonate. These projects aren’t easy, but they can be done!

So why was the legacy code a problem?

The old application code resided within a monolith which made our releases slow, environments difficult to configure and testing difficult. The frontend used Jakarta Server Pages (JSP), a pattern that interweaves Java code with HTML. This worked fine at the time, but over the years became increasingly misaligned with the rest of Rightmove’s frontend ecosystem.

Some of the pain points we experienced with this app included:

Actively trying to develop on an application like this presents a number of challenges and it was clear we couldn’t stick with the legacy frontend for much longer.

Microservices to the rescue!

We decided to rebuild the app from scratch into several cloud-based microservices. On the frontend, we paired React with an Express/Node backend-for-frontend, while on the backend we created a new service to manage the saving and retrieving of reports. We also leveraged an existing GraphQL API for fetching data. This allowed us to separate concerns and align with the rest of the Rightmove architecture, as well as:

Innovation through a new PDF service

We were also able to innovate by introducing a new microservice to produce PDFs of the final reports. We opted for a solution using Puppeteer, which provides more flexibility around PDF generation than some other third party libraries.

The PDF flow is fairly straightforward:

  1. The service receives JSON input, containing all the fields required for the PDF.
  2. The JSON is passed into React components representing the PDF template.
  3. Static HTML is created from these React components.
  4. Puppeteer spins up a headless Chromium browser, loads the static HTML and any CSS, and produces a styled PDF.

The big advantage of rendering it in a browser environment is that it fully supports CSS3 and JavaScript, so we can build complex and well-styled layouts with relative ease. That also means we can skip the steep learning curves and restrictive components sets offered by other PDF libraries. To further sweeten the deal, the approach is generic enough that other microservices across the company can use it too! 💪

Challenges and lessons learned

So far, I’ve condensed several years of work into just a few paragraphs. Although it may sound like a linear journey, it definitely wasn’t smooth sailing the entire time. As a team, we overcame late evolutions to requirements that weren’t in our control, complex pieces of work around permissions/user types, and finally challenges around migrations and onboarding. We already had beta users on the new app so minimising disruption to them was a critical requirement alongside getting the rest of the features done. In a sense, this meant finding ways to perform gradual open-heart-surgery on the new application.

A genuine highlight to come out of those challenges is that we achieved our goal of minimising user disruption. This came down to a few key practices, which were a mix of things we were already doing and processes we adopted.

Each of these lessons strengthened the project and how our team approaches this kind of large-scale decommissioning work in general (though sadly we’re not done with legacy systems just yet 😄).

Parting thoughts

The new tool is now live and already making a measurable difference so far. It’s faster, easier to maintain, and better aligned with the rest of the company architecture. On top of that, our PDF service is now ready to be reused and start supporting other teams.

Decommissioning is not a glamorous topic, but it is a necessary one. Hopefully this post has shown that with the right approach, it’s possible to modernise and innovate while keeping user disruption low. If we can do it, you can too!

Exit mobile version