Designing a Monolith: The Series

I have shamelessly built monoliths for the last 14 years. During that time I have produced dozens of Ruby on Rails applications that live in production today, in addition to being a team lead on architecture and code design on more than one team.

I want to share that knowledge with you. I want to help you design, build, scale, and maintain your Ruby on Rails application better.

I’m going to change the way you think about your MVC applications. I’m going to make you think twice about hitting that Rails generator. Ultimately, I’m going to influence how you write code, too.

In an upcoming series I’ll architect Spotify as if it was a Ruby on Rails application. I’ll go over class design, directory structure, advanced Ruby on Rails patterns, separation of concerns, modular architecture, database schemas, and more. It’ll be low on code and rich in thinking, code strategy, design, and architecture decisions.

Here’s why:

On Wednesday, September 23rd of 2020, Shopify released Packwerk: A Ruby gem used to enforce boundaries and modularize Rails applications.

The release was posted to /r/ruby and it received a bit of fanfare. The discussion varied but quite a few people expressed distaste for the release, citing how it shouldn’t need to exist.

/u/solnic made a very good point about mindsets that I think is worth repeating. At the very least, it’s something I will carry forward in my career.

I wouldn’t underestimate the impact a framework can have on not just the design of an application but also the mindset developers have. If you take a really close look at the Rails community, you will see that. There are OSS apps built with Rails that you can examine to see how people end up with codebases that are really hard to maintain. This happened mostly because they followed Rails conventions which just don’t work well after passing a certain level of complexity and/or scale.

I agree with the first part of this statement:

I wouldn’t underestimate the impact a framework can have on not just the design of an application but also the mindset developers have.

While Ruby on Rails doesn’t actively promote building monoliths, it doesn’t do much to stop you. Its creators have built and scaled their monoliths, but that information hasn’t trickled down to the community for one reason or another. This has left a bad taste in the mouths of many Ruby on Rails developers and has perhaps placed a curse on the community at large, that all Ruby on Rails apps are disgusting unmaintainable monoliths.

The second part of the statement leaves some room for discussion:

This happened mostly because they followed Rails conventions which just don’t work well after passing a certain level of complexity and/or scale.

Two very distinct skills are being clobbered into one here, and it’s rather unfair. The two skills: architecting applications, and writing code.

Designing and architecting applications is not the same as writing code. All because someone is an expert on algorithms doesn’t mean they’re going to be a good developer for your product team. All because someone has a degree in food science doesn’t mean they’re a good chef. All because someone has a degree in geometry doesn’t make them a good architect.

All because you write code doesn’t mean you’re a good architect.

Architecting applications is a craft. It’s about forward-thinking. Good architects are well-read in codebases. Good architects have been exposed to different ideas and patterns and have built with different ideas and patterns. Good architects are not forged from writing the same application year after year — not to say they aren’t a master of their own application.

Good architects think in terms of progression, asking endless “what ifs” and “how would we … if we” while not artificially handcuffing or constraining code to fit all the “what ifs” but allowing for future flexibility with relative ease.

Good architects don’t necessarily write good code, either. Just like how a good industrial architect wouldn’t necessarily build a good speaker box.

Back to the Reddit discussion.

There was another comment, by /u/zitrusgrape:

this is why i hate rails and what it promotes.

To which I replied. It’s also the reason why I’m writing this post.

It’s not a framework’s responsibility to tell you how to architect code. Sure, some frameworks are smaller than others, and sure, some frameworks have a more clear separation of concerns. Some frameworks promote vastly different architectures and patterns than others. Hanami immediately comes to mind, as does Trailblazer.

Ruby on Rails is MVC. But that doesn’t mean you can’t have a well-architected MVC application.

This series is going to be opinionated. It’s going to be seen as “not the right way” by many, too. I want it to because I want that discussion to take place. It’s something that needs to happen for all developers, so we can all write better code.

Because without open discourse we have nothing.