DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Cover image for A JavaScript monolith ready to scale
JoelBonetR
JoelBonetR

Posted on • Updated on

A JavaScript monolith ready to scale

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`);
}
Enter fullscreen mode Exit fullscreen mode

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.

Project structure



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?

Let me know in the comments!

Top comments (6)

Collapse
 
fyodorio profile image
Fyodor

Very interesting and practical approach, thanks πŸ‘

I’m curious (and didn’t find any direct answer yet), will Next bring any benefits as compared to barebones React app in case you already have an API app in (let’s say) Fastify? Does it make sense to introduce additional abstractions?

Collapse
 
joelbonetr profile image
JoelBonetR Author • Edited on

Hi @fyodorio it just depends on your needs.

Even if you've your services/micro-services on a different place, you can use the Server Side Rendering feature, this way your web app will be SEO-friendly.

Next Js is a framework (that implements React), so it brings a bunch of features on the top of it.

Maybe you find any feature that suits your project/s (Image or Fonts Optimisation, Routing, Static File Serving...). Also when dealing with more than a single project, using a framework can be a standard way to deal with those common tasks.

If you don't need (and analysis suggest you won't need in the future) SSR nor SSG and also you've the services somewhere else then maybe React is more suitable 😁

If it's the case and you go for React "only" I still recommend you to do a PoC with Next just to get some experience and find opportunities to use it later on.

So answering the question: Yes, it bring other sweet benefits, the question is if your specific project needs are aligned with what Next can offer πŸ™‚

Collapse
 
giovapanasiti profile image
Giovanni Panasiti

How would you handle authentication in such architecture?

Collapse
 
joelbonetr profile image
JoelBonetR Author

No differences with most architectures, you can define and implement whatever suits better to your use-case.

e.g. With a middleware, creating your /api/auth and handle it by yourself, using third party services...

Collapse
 
britzdylan profile image
Dylan Britz

Great work

Collapse
 
joelbonetr profile image
JoelBonetR Author

Thank you! 😁

🌚 Friends don't let friends browse without dark mode.

Sorry, it's true.