Why and where you should use Node.js
Table of contents:
1.Why should you consider using Node.js in your next project?
- Easy to learn
- Active open-source community
- I/O highway
- Developer productivity and satisfaction
- Real-time applications
- High throughput APIs
- Streaming services
- Enterprise applications
- SQL and NoSQL
1. Why should you consider using Node.js in your next project?
Easy to learn
Active open-source community
I think the next cool feature right after the non-blocking I/O operations (communication between the system and the outside world) are open-source packages from the NPM (Node packages registry). By the numbers, there are more than 1 million active packages at this moment in the repository. Last week downloads reached 14 billion and last month over 61 billion! The numbers are tremendous.
The core thing about Node is the Input/Output operations and how they are handled. I/O operations are for example a database call, getting file, calling an external service, etc. In Node, we have the event loop which stores all incoming requests which are blocking operations in the loop with their callback functions. Callback functions are called right after finishing the blocking operation. With this solution, Node is not blocking the main thread and can handle new requests. Such feature allows us to handle more requests compared to threads solution from other languages.
Node allows you to scale concurrent requests to more than other languages can do out of the box. Some guys achieved scalability levels of over 1 million concurrent requests and over 600,000 WebSocket connections. Of course, it’s a matter of the work you do behind each request and how many resources you have, though Node is still good at scaling things up.
Compared to Java, below some point defined by the number of Java threads, Java is better in handling concurrent requests, because threads are faster. Though Node, after that point is going higher in the number of concurrent requests and Java stays with the same maximum. Of course, if you write bad code, you’ll have 10 requests per second instead of 1000. In general, it’s easier to write scalable solutions in Node.
Its limits here are mostly about CPU usage due to the fact that the whole application is running on a single thread. You can’t fully use the CPU power. To scale things, you need to create a Node Cluster, use things such as PM2 node process manager or scale with Docker if you run Node inside a Docker container.
Developer productivity and satisfaction
The freshness of the technology gives developers the power to make great software. It’s ten years old now. In contrast, Java or PHP appeared more than 20 years ago, so it’s still pretty young. That and less boilerplate code, easy asynchronous programming, and elastic JSON manipulation makes Node.js developers happy while staying productive.
2. Where can you apply Node.js?
Node will more or less fit everywhere. When you want to do a quick minimum viable product to test your idea or you want to go enterprise, use Node. There are some caveats, however, the overall image of the Node ecosystem is good.
I wonder why every blog post about Node.js usage doesn’t say anything about simple API. Authors say that you can use it for sophisticated cases, but developers can use Node just to create your CRUD application. With ORM support for SQL or NoSQL databases, you can quickly expose your resources as an API. Perfectly fits MVP use case. No rocket science with project setup. Just write the API and launch your product.
In Node, it’s super easy to integrate with WebSockets such as Socket.io. WebSockets, give you the ability to create a duplex connection between the client and the server. With this, the server can send real-time updates to the user when something changes.
Example usage of WebSockets:
- Social feeds — update instantaneously user feeds with new posts without the need of refreshing the user’s browser
- Games — fire an action event and broadcast it to other players
- Document collaboration – document editing simultaneously by multiple users like Google Docs
- Clickstream data — analyze user movements and behavior on your site
- Real-time analytics and financial tickers — update instantaneously your charts in the client browser
- Instant messaging — live chat experience inside the client browser
If you want to scale your application automatically that will detect traffic spikes and scale up or down to match incoming traffic, serverless is a good option. It gives you the ability to pay only for the resources used during the execution, so you don’t need to pay monthly for monstrous instances that can handle that traffic.
There is one thing which I don’t like about serverless architecture. It’s the vendor lock-in problem, however, in Node.js we have a framework called serverless. It allows you to write serverless applications that you can deploy to any cloud provider with a consistent experience and that’s a pretty cool thing. It integrates easily with AWS, Azure, Cloudflare Workers, Fn, Google, Kubeless, OpenWhisk, Spotinst, so you can choose which provider fits your needs best.
High throughput APIs
The best examples of high throughput API are chat applications. You want to be reliable and fast when millions of users are typing messages to each other. Of course, chats are not the only example. You can use it everywhere where you need to work at a huge scale. Proper horizontal scaling such as app architecture on top of the AWS with Node.js I/O gives you the ability to achieve this goal. Nevertheless, it’s not a magic technology that will do it out of the box.
Imagine you have a video file on your server which weighs 20GB and your server has only 8GB RAM. You want to give a link to a friend to download it, so you just set up your server and endpoint and you give the link to your friend. Your friend clicks the link and after that, your server is going down due to out of memory error, because the server tries to load the whole file into the memory.
In Node you can produce an out of memory error, however, Node Streams come to rescue us. With Streams, by creating file stream in our endpoint, we are just increasing memory usage by 25MB (default chunk size), because Node is not buffering the whole file. It’s just sending chunks, one by one to the end-user. Moreover, you can transform the stream on the fly. So for example, if you’d have a text file that would weigh 2GB, you could just make an uppercase of all letters in each line on the fly without loading the file into the memory. With those possibilities, you can create your own Netflix clone or any other streaming platform.
Java is super enterprise. Many treat Node as an MVP tool. However, in my opinion, that’s the matter of used tools. Many use the Express.js framework, which is elastic, good for rapid development. Although it’s used by many incompetently and that leads to non-enterprise software.
SQL and NoSQL
Many say that SQL support is worse in Node. Two years ago I would say that Node.js should only be used with NoSQL databases because working with NoSQL is a pleasure and with SQL is not. However, nowadays SQL tools are much better. For example, there is the Sequelize which is pretty good when you need to create CRUD operations and there is also Knex which can be used when you need to perform some advanced queries. I like query builders, however, Java query builder called jOOQ is at the top of my list, sorry Node!
Node.js SQL tools are not more complicated, I mean here the syntax, than NoSQL tools. They are at the same level, in my opinion. So, yes, you can use Node.js with the SQL database, no worries.
As history shows, NPM had some failures. One of them was about the 11 line Node package which was adding characters to the string — named “left-pad.” On March 22nd, 2016 this package was deleted from the repository and it resulted in world chaos in the Node.js environment. Many projects couldn’t be built on that day. Fortunately, NPM fixed the problem by making it harder to unpublish a version of a package.
Another thing about NPM vulnerabilities, on the 6th of January, David Gilbertson published an article “I’m harvesting credit card numbers and passwords from your site. Here’s how.” It shows how any hacker could inject malicious code in the package code and the package could be installed not as your first party, but even as a third-party package. To be more precise, it’s not only a Node.js problem, but it appears also in almost any frontend technology which uses NPM. What we can do about this?
- Keep checking npm audit security report.
- Choose the packages you use carefully. Use more popular ones.
- Have fewer dependencies.
3. Practical implementation
Recently, we’ve experienced the practical implementation of the article, with some extra social engineering attacks. One owner of a popular NPM package didn’t want to maintain the package anymore, so he gave maintain access to the guy who had previously asked him if he can do it for him. Unfortunately, the guy was a hacker and has added two lines of code which were importing the hacker’s package which was hijacking user data. The package was published with a malware subpackage. After that many NPM packages were updated with newer package version and the hacker could steal the data that went through applications which had the hacked package inside.
To solve the problem many packages were updated to the previous non-hacked version. It’s not a problem only of the NPM. It can appear in any language library, some will be secured, though some will fail. A solution could be to not use the newest version. For example, update the package version every two releases or more, so the version has time to be verified.
So as you can see there are some pitfalls for which we need to be ready when we use NPM. Nevertheless, it’s still the best repository of libraries among all programming languages in my opinion, because you can find almost everything here. You want to generate pdfs? NPM has it. Work with colors? No problem. Sprite sheets? Sure, that and everything else you can find in the NPM. Just remember about security checks and you’ll be ok.
4. Node.js limitations
There is one more thing, namely, CPU usage. Node is very efficient when you try to do many I/O operations, however, if you’d like to use Node for e.g. image processing, just don’t. Due to its design, it operates with a main single thread and it is not suitable for heavy computations. An application can’t scale one process to all available CPU cores and it’s a little bit slower than Java, for example. Node wins when you need to do plenty of I/O operations, but in this situation, you’d need to choose another language such as Java or Python. Of course, we can use 100% of available cores thanks to the Node Cluster, however, it will create new processes, so we will gain only more requests than we can handle, no CPU power to compute heavy stuff.
5. So are you ready for Node?
In summary, you need to define what your product needs to do. I’d say that the only no-go is when you need to do heavy computation. Although, you can use Node as a service that will handle the traffic to your other service that is doing heavy computations.
It will fit in most cases. Now with the Nest as an enterprise framework, you can’t say no to Node.