MEAN: the monolith crusader.
The MEAN stack is a popular set of components used to build modern web applications. It’s quite a bit different from how we’ve architected systems in the past and offers the chance to build maintainable, scalable, fast systems. But first, let’s talk about the old way to build a web application.
The Monolith is that project you’re probably working on right now. It’s that Rails server that some long-gone consultants or ambitious 10x developers threw together to get the prototype out but now you’re maintaining it. It’s still on Rails 2.3 and even though Rails 4 is out, you have no idea how you’re going to be comfortable enough updating it to Rails 3.x.
It sucks to work in, it’s on a framework and language version so old it’s not even supported anymore. It’s hurting recruitment because no engineer wants to learn an old system.
The system contains a lot of expensive front-end and back-end code. The cost of a rewrite seems outrageous before you would even begin such a project.
Eventually what happens is these projects do fall under a rewrite. Maybe not today, maybe not tomorrow, but someday it happens. A new monolith is built by another ambitious developer and the cycle begins again.
The rewrite happens in parallel with the existing system. Now the old code is understaffed with the less ambitious developers in the company — not that this is a bad thing, ambition isn’t necessarily a good quality for an engineer to have. The rewrite project drags on for twice the length of time it was supposed to, and when it finally does come out, it’s so full of bugs it had to be rolled back for another few months of bug fixes. The thing about software projects is they accrue tons of domain knowledge (why is that conditional there?) that is difficult to see when embarking on a rewrite.
This is not the developer’s fault, but the common web frameworks and conventions of today (Django, Rails) really encourage this kind of architecture. Put everything under one, opinionated roof and your product will be out the door quickly. The trouble comes later.
What you really need is the ability to segment out a system into smaller chunks so once something becomes outdated enough either due to performance, security, or product reasons, it can easily be swapped out. No throwing out the baby with the bathwater.
This isn’t microservices
Don’t get too excited about breaking up a system into tiny chunks. To be clear, I am proposing you split the system into 2 parts, the back-end and the front-end, no more. This process is not really one you do for technical reasons (though there are some), it’s one you do for human reasons. Having too many engineers in a codebase bottlenecks the entire project. A good number of engineers in a single codebase is probably 7±2.
Why not have a service for every part of the app? Because each service is another thing to manage, it’s another thing to log centrally, it’s another thing to give security patches to, another thing to monitor. There is a huge cost to adding a new service. Don’t get crazy with SOA. That’s worse than the monolith.
Still, architecting your application in this way puts you in a good place if SOA is a direction you want to head.
The MEAN Stack
This is in contrast to web frameworks that were popular last decade such as Django and Rails. These frameworks came batteries-included with heavy opinions on how your application should look. For example, they all came with an ORM that pretty much required you to use a SQL database.
Neither approach is good nor bad. They each have their merits and downsides.
The main advantage of an opinionated web framework is that the developer doesn’t have to think so hard when building the app or learning how to use it. There is a “right way” to do things and moving away from them is discouraged simply on principle. The downside is lack of flexibility. If you don’t like the CSS preprocessor that it comes with, it’ll be an uphill battle to switch it out for a different one.
The main advantage of a composable system that doesn’t have a heavy framework is that you get unlimited flexibility into how your application will work. The downside is you’ll want to be aware of all the options at hand, and you have to write your own boilerplate to plug it all in.
This is where the MEAN stack comes in. By sticking to some smart defaults of MongoDB, Express.js, Angular.js, and Node.js, you can start building your app right away as well as take advantage of plenty of documentation and existing boilerplate to achieve the same level of productivity you would have with an opinionated web framework. In other words, you can take the opinions but not be forced to use them.
The MEAN stack is made up of tools that pair well with JSON for this reason.
With every language/tool comes a culture, and the culture behind Node is one that really encourages back-to-basics coding. You’ll find yourself opening TCP sockets directly, making sure you only attempt to open a file once before using it, and working with an admittedly naive (but awesome) package manager. It’s a bit more work on your end, but the payoff is really knowing how your application works and not simply piling magic on top of magic (and we all know how that ends).
It’s been around since 2009 and plenty of very large systems are running on it. It’s a favorite of startups for its rapid development and huge open source ecosystem. It’s a favorite of enterprise for its performance and the simplicity pays off in terms of maintenance. Netflix, Groupon, SAP, LinkedIn, Microsoft, Yahoo, Walmart, PayPal, and Salesforce all use Node.js in production.
Express.js is the first and most popular web framework for Node. If you come from another languages “web framework” might be calling it a bit too much. It’s very simple and very basic. A simple server looks like the following:
That’s really about all it is. Everything else (database connections, authorization) is handled by you. Again, it’s more work to write this boilerplate yourself, but it gives you much more flexibility and knowledge about exactly what your app is doing. A bit more up-front work, but huge payoffs later when it inevitably stops working the way you expect. It’s also simply more fun.
MongoDB is a popular database choice for Node applications and the most popular “NoSQL” database today. NoSQL is kind of a silly term, it should be Non-Relational, but that somehow doesn’t have the same punch.
More importantly than no SQL is no tables. If all you know is SQL you might have a tough time understanding how MongoDB is different (and you’ll likely incorrectly use it the same way). If you’re a new developer and you don’t know SQL, you’re in luck. I know from teaching that people without DB experience often have an easier time understanding MongoDB than people with a SQL background.
MongoDB has collections, which are kind of like tables, but they’re different because they’re basically JSON documents and as such, support much more complex structure than a row would. For example, if you wanted to have multiple emails for a user, you would simply have a document like the following:
"user": "Jeff Dickey",
"emails": ["firstname.lastname@example.org", "email@example.com"]
MongoDB isn’t exactly JSON, it stores this in a format called BSON which is essentially binary JSON (fast JSON) but with a few more features. You can generally just think of it as storing JSON though. Also because it’s JSON it doesn’t have a schema. This means you can write your app more quickly without having to generate table migrations and gives you the flexibility to have heterogenous structure in your data.
It doesn’t have the same level of queryability as SQL and it’s missing some functionality like JOIN. However it is designed from the beginning to be horizontally scalable so when you need more DB power, you just add a new box to the cluster.
This means that the front-end code is separate from the back-end code. They’re still linked to some extent, the back-end server will serve up an initial page to bootstrap Angular, but after that the browser creates the page itself. This keeps the back-end really just a simple JSON API and prevents conflating it with the front-end code.
In other words, this prevents the Monolith.
All together now
Combined, these components allow you to build a flexible system. Using a stateless back-end you can scale up as many app nodes as you want (though you won’t need many with Node’s performance anyways). With MongoDB you’ll have a fast, scalable database.
Most importantly, your front-end is separate enough from the rest of your code. Nobody needs to be an expert in both. Rather than drive yourself to drinking over the thought of a rewrite, you’ll be able to rewrite just small components as technology improves and your product develops but continuing to stick to JSON as the lowest common denominator of your system.