A JavaScript monolith ready to scale
JoelBonetR 🥇
Posted on August 13, 2022
In many projects I use this stack to quickly getting the things done at the lowest cost possible.
Next JS provides both Node and React sweetened with built-in features like file-system based routing and much more.
If I need to create a project for a client (and assuming there's no showstopper or impediment to proceed this way after the initial analysis) I'll do the following:
1- Create a Next JS app.
2- Create a DB instance on my VPS (or any provider).
3- Add an ORM with the proper DB driver (I use Sequelize -mostly- or Mongoose but there are a tone out there, you can pick your favourite one).
4- Define the data model.
5- Add some validation library (I usually use Joi but as the ORM, pick whichever suits best for you).
6- Create a directory "api" inside "pages".
7- Add a folder for each backend entity like /pages/api/users
The index.js
inside will look something like that:
switch (req.method) {
case 'GET':
return await getAllUsers();
case 'POST':
return await createUser();
default:
return res.status(405).end(`Method ${req.method} Not Allowed`);
}
8- Add the view for this API inside pages, that's /pages/users
Which will use getServerSideProps
(see the API Reference) to fetch desired data from this API and show related data.
If you need a component instead, simply create a directory in the root like components/users
, then you can import your React components in your pages.
Repeat steps 4 to 8 for each entity you need in your project.
You can even convert it into a PWA easily with Next-PWA.
Scaling the monolith
Because it will probably grow in both code and -hopefully- customers.
If you already know that this project will need to handle thousands of concurrent requests you may prefer to start with a different architecture but in most cases I face you simply don't know how the project will do. That's because it depends on many factors, most of them are on the client's roof and some of them are not even under client's control.
1- The first step in scaling the project would be increase the amount of resources of your VPS or cloud instance. e.g. If you started with 2 vCores and 2Gb of RAM, maybe you'll need to scale vCores, RAM or both, depending on what's your App doing and your hosting provider plans.
2- When this is not enough or there are forecasts of heavy traffic, you can simply split your /api/ directory and run it on a Node server in a new instance. That change requires few changes on both /api/ code and frontend code. e.g. changing your calls from localhost for a different thingy (if you handled that with env variables congratulations! it will cost like 2 minutes) and wrapping the /api/ inside an Express plus adding some routing.
At this point we separated the frontend from backend 😁
3- If this is not enough, you can then chunk your APIs and provide them through different instances.
Let's say we've conceptually 3 APIs inside our app users
, businesses
and stats
and our favourite monitoring tool shows us that stats
is consuming the 60% of the resources. We can move Stats following the same steps into a fresh instance, releasing a good amount of load from the other.
Following this conceptual guide we add costs just when the project needs them.
Please note that each step forward into a fully fledged micro-services architecture doesn't eliminate the complexity, it's moving the complexity from the code to the infrastructure thus I recommend to check some DevOPS concepts to make it less of a burden.
Do you want a full tutorial on that with code, screenshots and examples? Maybe discuss some step?
Posted on August 13, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.