You are here

Small Bites into Polylithic Architecture

 

If there is a topic the engineering team loves discussing fiercely, it would be how software is designed. Over the years, we noticed this common pattern appearing in projects, with a pragmatic and sensible approach to growing outward. What do you call a service oriented API that connects with many clients? We couldn’t find a suitable term for this new pattern, so we call it: Polylithic Architecture.

Why the monolith works

A monolith is an application which combines the user interface (UI) with the business logic into a single piece of software. The boundary between what the user sees and what the application does can easily blur since each part of the application is easily accessible from the others.

Monolithic architectures are great for initial development speed and simplicity. Having an entire project within one codebase allows a relatively small amount of developers to build features quickly. We simplify the development and debugging cycle when the server generates the presentation layer. Deployments are simpler to manage, since we only need to worry about one deliverable.

Monolith Diagram. Note the Presentation UI and Business Logic in the same package

Monoliths accept the tradeoff of tighter coupling of UI and business logic for convenience. Tight coupling is when one part of a software heavily depends on another. Changing a feature usually propagates to other areas of the code. This is a practical decision, and most projects  can take the tradeoff to test ideas. 

Despite this tradeoff, the monolith is an excellent choice in some situations. In early stages of development, such as proof of concepts or first revisions of web only applications, the monolith is a champion in speed and productivity. Many budget-tight projects have been saved by the monolith. 

Monolith difficulties

Tight coupling increases difficulty for future changes to the application. Developers will need to consider a system in it's entirety before deciding on how to change parts of the code. Changes to the business logic bubbles down to changes in the UI, leading to ever-increasing development time.

Scaling is an expensive challenge. Tightly coupled pieces must grow together, even if we only need to scale one area. When we look at usage data, some areas of an app are used more than others. These hot spots are the problem areas we would like to scale and adjust. Within a monolith, the entire server grows. This leads to nonoptimal cost increases to support the app.

In theory, a well designed monolith can maintain a looser coupling and gives a business flexibility for change. When we create strict boundaries in our application, and have very well defined concerns, a monolith can be maintained as easily as any other architecture pattern.

In practice, monoliths require strong group discipline to maintain strict application boundaries. Regular code reviews and refactoring keeps a team focused on good architecture. Having an extensive test suite helps our team make changes with confidence. These are good practices that any software team should implement for the sake of maintainability. 

Monoliths lead themselves to redevelopment once our application’s performance needs are critical. Adding new features take an increasingly longer period of time, whether it comes from testing or preventing regressions. New members to a development team will take a much longer time to understand the original system design which will increase the ramp-up time.

It can be very difficult applying new lessons learned during development to maintain backwards compatibility. Systems critical to our business are worth re-examining, refactoring, and doing right.

The rise of the mobile web of things

The mobile device revolution changed the way we look at server-based applications. Mobile users now expect high performance and highly interactive mobile friendly applications that work well in low-bandwidth situations. Monoliths are designed to only interact on a web interface.

Monoliths stay relevant by using Responsive designs. Mobile friendly web applications are designed to look well on mobile devices and try to emulate native app behavior. This is a good step for a monolithic application to be compatible with mobile devices.

Integrating a native app with our server-side application requires specialized separate protocols. Since the interface and some business logic is handled by the native app, we only need to send and receive the data. We decoupled the business layer from the UI for mobile users, turning part of the monolith to an API.

While this is a great design decision, we introduce a new separate coupling between the API and the web interface. We cannot scale the API portion independently. The web application must grow, which can lead to unnecessary scaling and costs.

New horizons: the anything of everything

Modern applications operate on all interfaces, not just 2D screens. In the past few years we were introduced to a slew of new devices. The rise of apps in the car, in home appliances, and smarter TVs. Innovation opened up a new category of design: non-visual programs. Our applications can now work with messaging robots, digital assistants, audio-centric helpers and IoT integrations. All are designed to improve our business needs without the need of a screen.

We now connect our applications to more than just users. Third party applications, for analytics, reporting and integrations, are very common separate integrations that development teams create. That means ensuring business rules are unified across multiple integrations.

Is there a better architecture for connecting to all these types of integrations?

Polylithic Architecture

The polylith is the natural progression in designing an application where the end-device, or client, is uncertain. While the device we interact with will change, our business rules remain the same throughout the process. 

The polylith starts with the business logic core (API). All interactions of data occur in this core, leaving the UI responsible for handling the user desires. We follow an API First methodology while designing all interactions and processes of data in this area. 

UI clients are created for each interface, tailored to each different user experience. Having many small projects that focus on the client’s individual use case is easier to understand than one very large project with special cases everywhere. 

To unify interactions, UI clients only interact with business logic via remote API calls. This is where we define our boundary and how interactions should go. By design each API call follows a strict contract with well defined rules and actions. Since the business logic should remain the same regardless of device, each different client would have the same contract.

Benefits of a Polylith

The polylith gives us the flexibility to make architectural changes without affecting the other areas of the app. As long as the boundary rules are maintained, we have the freedom to change our backend language to something faster or our frontend to something more productive/current.

We can identify the problem areas easier and scale them without affecting the other areas of the application. This gives us a better way to react to rapid changes with better cost management.

The business process stays in one place. This makes it easier to manage changes to the entire workflow process. Adding new processes may need to involve client changes but modifying existing processes is easier.

In larger projects we can isolate different responsibilities of the polylith and UI to individual developers. UI developers can focus on their sections, as long as they’re following and fulfilling their API Methodology. API developers focus on optimizations and ensure business processes work together. 

We can reduce our test suites to focus on specific portions of the application, leading to quicker development turnaround times. Our data sources that follow the contract can be faked in automated tests allowing for faster deployment schedules.

Closing thoughts

Polylithic architecture takes a deeply coupled business logic layer and turns it into an independent entity of the app. Migrating an existing monolith to a polylithic architecture allows for additional flexibility without needing to throw everything out for a restructure.

This is a natural progression of your application’s architecture.  Depending on your scaling needs, a polylith is well suited for expanding your business capabilities.

Fresh Lines is a Web and Mobile Development company that can help with Web Applications, Mobile Applications, Marketing Sites and Voice Services.

Contact Fresh::Lines Today!