Large Application Architectures
- development
- rails
- 974 words
A relatively brief discussion of different ways to structure a large and ever-growing web application for long-term sustainability.
This isn’t meant to be a comprehensive comparison of the solutions discussed, nor is it a one-size-fits-all solution to applications architecture. The main purpose is for me to work through some options.
tl;dr: microservices are great if you need them and have the resource
The context here is:
What I want to explore is how to improve the architecture of this application from “monolithic ball of mud” to something more maintainable.
From the diagram above, and in line with the requirement for high cohesion there are two desirable architectures to choose from:
The Modular monolith
Because this is a Rails app we’re talking about this means: ruby modules, rails engines or component-based rails applications.
Microservices
Or, more generally, Service-Oriented Architecture. I’ll use these interchangeably and avoid getting bogged down for now.
The plan is to evaluate the pros and cons of each choice, and to select one based on the context of $DAYJOB
. Your mileage will vary.
These two options do share some similarities when used properly:
The implementation of these features varies, and how strictly they are enforced by the technology varies, but in principle, the two offerings provide many of the same benefits.
Only insofar as we need to do a bit of design. Not too much, but not so little that the application rots.
I was really just looking for an excuse to include this:
Let’s take a look at that context from earlier again:
With all of this in mind, I’m leaning towards the modular monolith for the following reasons:
the additional short-term and ongoing complexity of managing a suite of distributed services is not achievable with the current size of the team, and any long-term complexity benefits of SOA cannot be bourne by a team this size
the additional operational complexity is not achievable without additional specific ops or devops resource
the large-app onboarding problem can be partially solved using sufficiently detailed documentation3
much of our business-critical data is quite tightly coupled and interdependent due to the nature of the business; writing course-grained APIs to make this performant could potentially be quite cumbersome
the cost of accidentally building a distributed monolith is too terrifying to even consider
the resource required to upgrade a rails app of this scale feels (I have no data, just my own experience) less than maintaining a complex distributed system
The following criteria being met is a good indicator that a given product/service should not be a module within the monolith:
there is very little data coupling, or it’s mostly unidirectional
the service requires crossing some security boundary
the service has a different paradigm to the main application
or, I stand on the shoulders of giants