Big Sofa Tech Blog: Rebuilding

In previous blog posts, we wrote about our decision to rebuild some key aspects of the Big Sofa platform. This post details how we are rebuilding the platform’s front end, the major benefits this brings, and how we are approaching some of the technical challenges that it presents.

Growing pains

Originally, our front end code was embedded in the monolithic Ruby on Rails application that powered the Big Sofa platform.

The demands of growth and the natural accumulation of technical debt meant that our front end was starting to require more maintenance, and it was taking more time to release all the new features we wanted to get out.

We wanted to give the code greater consistency and cohesion; like lots of evolving platforms, it used a mix of libraries and JavaScript written in different styles by developers who had worked on it in the early days. This made it more complicated to conduct testing, and without a standard way of doing things, it took longer to bring new developers on board.

Because front end code is intermingled with back end code in a monolith, making changes in one area can cause unintended consequences (aka bugs!) in other, seemingly unrelated areas. Developers needed knowledge of the application’s back end to feel confident in making changes to the front end without breaking anything. This blurring of responsibilities made it harder to hire the front end specialists we needed to support our growth.

Being so tightly coupled with the back end also meant that it wasn’t possible to test or deploy the front end separately. The tiniest of changes to the UI would mean running the platform’s extensive suite of automated tests and deploying a new version of the entire application. A comprehensive test suite can instill confidence that your application is working as expected, but waiting for it to run every time you make a minor text change impairs your ability to “release early and often”.

Benefits of a decoupled architecture

In contrast to a monolithic architecture, a fully decoupled architecture is one in which the front end and back end are entirely separate applications. They can be tested and deployed independently, and communication between them is via an API. The Single Page Application (SPA) on the front end requests and consumes data from the API and is responsible for rendering the UI.

Adopting a decoupled architecture had many potential benefits. It would mean that we could work on the front end without depending on the back end. An API endpoint that the front end requires doesn’t exist yet? No problem. Pass mock data to the front end and continue development without being blocked.

We would also be able to make changes to the front end without having to redeploy the back end and vice versa.

It also becomes easier to hire front end specialists. Clear separation of concerns between the front and back ends means that we can hire developers who specialize in each area. When dedicated front end and back end teams can work simultaneously on a particular feature, development velocity increases, and we can deliver new functionality faster.

Defining our requirements

Having decided to rebuild the platform, we knew we wanted to extract the front end and rebuild it from the ground up with an entirely new, modern tech stack.

Our objective was to migrate to a fully decoupled architecture, with standalone front end applications communicating with our backend microservices via a well-designed and robust API.

We scoped out the project and defined the requirements for the new front end. It would need to be:

Built using a modern Javascript framework: We chose React for its declarative, component-oriented approach to building UIs, as well as its dominant market share and vibrant ecosystem.

Fully decoupled from the backend: The new front end would be a standalone application, deployable independently of the back, and only communicating with it via the API. It would receive JSON data from the API and be responsible for rendering its UI. We had recently begun separating the back end into microservices which communicated via an API. This nascent API could also power a new front end experience.

Styled with a consistent design system: Creating a design system and all of the components we needed from scratch would have increased the length of the rebuild considerably. We used the Material UI component library to give us a head-start. It’s a collection of pre-built React components that incorporate Google’s Material Design principles. We didn’t have to worry about building low-level elements like buttons or form fields, which saved us a lot of time, and the design system helped us apply a consistent look and feel across the platform.

Testable: We used Jest and React Testing Library to write automated unit tests for our components. We enforced minimum limits for code coverage to ensure that we tested them thoroughly.

Maintainable: The codebase should be well-organized and documented. Small, well-designed, modular components with a single responsibility should be composable into more complex features. Best practice coding standards should be adopted so that developers new to the codebase can familiarise themselves with it quickly. We use Storybook to help us build our UI components. It’s a development environment that allows you to browse a component library, view the different states of each of your components, and interactively develop and test them. It’s incredibly valuable to be able to have a living style guide of all the components in your application.

In the next installment of this blog, we’ll discuss the migration path we chose, and what’s coming next from Big Sofa.

Our technology transforms video into behavioral data to illuminate authentic behaviors in the spaces and places they occur.