Hacker News new | past | comments | ask | show | jobs | submit login

Check out these two articles from Shopify on their Rails monolith: https://engineering.shopify.com/blogs/engineering/deconstruc...


Specifically relevant to the discussion is this passage:

> However, if an application reaches a certain scale or the team building it reaches a certain scale, it will eventually outgrow monolithic architecture. This occurred at Shopify in 2016 and was evident by the constantly increasing challenge of building and testing new features. Specifically, a couple of things served as tripwires for us.

> The application was extremely fragile with new code having unexpected repercussions. Making a seemingly innocuous change could trigger a cascade of unrelated test failures. For example, if the code that calculates our shipping rate called into the code that calculates tax rates, then making changes to how we calculate tax rates could affect the outcome of shipping rate calculations, but it might not be obvious why. This was a result of high coupling and a lack of boundaries, which also resulted in tests that were difficult to write, and very slow to run on CI.

> Developing in Shopify required a lot of context to make seemingly simple changes. When new Shopifolk onboarded and got to know the codebase, the amount of information they needed to take in before becoming effective was massive. For example, a new developer who joined the shipping team should only need to understand the implementation of the shipping business logic before they can start building. However, the reality was that they would also need to understand how orders are created, how we process payments, and much more since everything was so intertwined. That’s too much knowledge for an individual to have to hold in their head just to ship their first feature. Complex monolithic applications result in steep learning curves.

> All of the issues we experienced were a direct result of a lack of boundaries between distinct functionality in our code. It was clear that we needed to decrease the coupling between different domains, but the question was how

I've tried a new approach at hackathons where I build a Rails monolith that calls serverless cloud functions. So collaborators can write cloud functions in their language of choice to implement functionality and the Rails monolith integrates their code into the main app. I wonder how this approach would fare for a medium sized codebase.

shopify's problem can be fixed without microservices by writing modular code. The monolith should be structured as a set of libraries. I find it so strange, the way these microservice debates always assume that any codebase running in a single process is necessarily spaghetti-structured. The microservice architecture seems to mainly function as a way to impose discipline on programmers who lack self-discipline.

That's the approach described in this article: https://medium.com/@dan_manges/the-modular-monolith-rails-ar...

Instead of an app directory you put all your code into gems and engines.

Shopify has taken the approach of siloing their monolith into smaller rails apps which is a similar approach to refactoring into rails engines.

    The microservice architecture seems to mainly function as a way
    to impose discipline on programmers who lack self-discipline.
Sadly we're discovering that while that's the goal, the actual result is frequently Distributed Spaghetti.

Oh dear, it seems I've lost my poor meatball.

Well seeing as Italian-Cuisine-Driven Development is so crushingly prevelant, it seems most average developers within one standard deviation of ability on the normal distribution lack either discipline, know-how, or time. Or any combination of the three. So it's hard for software not to be spaghetti unfortunately. That's the natural state it wants to be in over time.

Microservices won't change any of those variables. Nor will it change the normal distribution of them. So one thing is for sure. No matter what the architecture of paradigm is being used, we can on average expect average quality software. Most people on average don't gush about how amazingly clean their architecture is or how well defined their bounded contexts are. They tend to talk about spaghetti. I infer from that that on average it's spaghetti and theres a chance it might not be.

1400 people work on Visual Studio, no microservices possible.

Modular code

> All of the issues we experienced were a direct result of a lack of boundaries between distinct functionality in our code

This is the key lesson to learn: if you are struggling to have clear separation of responsibilities, you are going to have a bad time with either approach. To the extent that a replacement system ends up being better it's probably due to having been more conscious about that issue.

Microservices at least force people to draw a line in the sand between subsystems/services. How effective or useful the lines you draw are, that's up to the skill of the engineers building your stuff.

I'm not saying microservices are better, but people should really take more serious considerations between the boundaries between subsystems. Because it's so easy to create exceptions, and things end up infinitely more complex in the grand scheme of things.

Clear, well-defined boundaries matter. It's the only way a developer can focus on a small part of a problem, and become an expert at working on that subsystem without needing greater context.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact