what is nodejs used for
April 28, 2020

Programmers Guide: What is Node.js Used For?

Open Source
Development

Why Use Node.js?

Speaking as an old-school enterprise Java programmer, I often feel like I need to make two separate confessions when I talk to people about Node.js. First, I have to confess to my peers that I really, really like Node.js. This often gets mixed reactions ranging from excited agreement to outright disgust. Second, I have to confess that I really didn’t like it at first, even though I’ve been working with Javascript since the late 90s. This runs the risk of scaring people off of a platform that I’ve grown to love.

Examining my own feelings on the subject, I realized that a lot of my early aversion to Node.js was really borne out of the language asking me to do things that I had deemed unseemly practice in more disciplined languages like Java.  If I’m being 100% accurate, my first hesitation was even earlier than that – it was the very act of trusting an ‘undisciplined’ language like Javascript to control my precious and critical backend logic!

Guide to Node.Js

As I began to explore the language, and perhaps more importantly its architecture and ecosystem, I realized that I was simply asking Node.js to be something it was not. I was asking Node.js to be an old school language. It didn’t take much of a leap then for me to realize that the problem was with me, and that what the world really needs is an old school programmers guide to Node.js.

A proper guide could fill several volumes, and maybe someday it will.  In the meantime, I want to at least highlight some of the exemplifying and/or unique aspects of Node.js which might be problematic at first to those new to the language, and which were most certainly problematic for someone with my kind of background. 

Asynchronous vs. Synchronous Workflow

The first impasse that most old school developers reach when they encounter Node.js is the inherently asynchronous patterns. For developers that are used to doing things in order, it can be frustrating to not be allowed to take for granted that Node.js doesn’t want one part of the app to “care” about the progress of another part of the app.

But, what do Twelve-Factor apps tell us about the way we should think of our processes?  The Twelve-Factor app tells us that we should think of our processes as isolated, stateless processes.

Why? We want those processes to be ephemerally executed, capable of being passed from one execution environment to another seamlessly without interruption to program workflow. Why again?  So that our apps can execute as much of their workflow in parallel, and therefore across as many horizontally scaled compute resources as necessary.

These days increases in compute capacity are not originating from advancements in processor clock speed, but rather in the number of individual cores that we can shove into to a board.

In order to take advantage of that additional capacity our applications must be capable of utilizing those cores simultaneously rather than waiting on individual components to finish their work.

Node.js's Architecture Event Loop "Libuv"

At the core of Node.js’s architecture is an event loop library called “libuv.” Libuv is responsible for interpreting units of Javascript work from the code provided by the developer and queueing those requests as asynchronous events.

Each unit of work is executed in its own isolated instance of the V8 Javascript Engine, and so you achieve basic thread safety. This does happen at the cost of having to provide meta information along with each unit of work, but, for the most part Node.js hides this from you and you don’t need to worry about it.

node.js architecture

Even though the benefits of building a language that does this inherently may now be clearer, that doesn’t make it any easier for newcomers to deal with asynchronous programming semantically. The EventEmitter class can make this experience much easier. Rather than nesting functions and callbacks, you can treat each of your work units as events.

var events = require('events');
var eventEmitter = new events.EventEmitter(); 

var ringPhone= function ringPhone() { 
	console.log(’brrrrrr-ring, brrrr-ing, brrrrring…’ );
} 

eventEmitter.on(’incomingCall’, ringPhone); 
eventEmitter.emit(‘incomingCall');


The more recently introduce async/await functionality can also help developers who are used to a more procedural syntax:
 

const getData = () => {
   fetch('https://jsonplaceholder.typicode.com/todos/1')
     .then(response => response.json())
     .then(json => console.log(json));
};

It can then become:

const getDataAsync = async () => {
    const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
    const data = await response.json(); 
    console.log(data);
 };

Objects and Typing in Node.js

Javascript is simultaneously a functional language and an object-oriented language. In Node.js, you can create classes like you are used to in Java, and you can also treat functions as first-class citizens, i.e. you can pass them as if you were just passing a normal variable:

function callMeFirst(callMeLater) {
    callMeLater('my first message');
}
callMeFirst(
  (message) => { console.log(message) }    This is an ‘anonymous’ function being passed 
);

I find it’s helpful to just practice coding with a debugger. It takes some getting used to creating breakpoints on your code and introspecting them to see the function and meta data structure that Node.js uses to encapsulate your functions.

If you think if that structure as being essentially just an Object, and that Object contains some executable and evaluatable Javascript code as well as some meta-information that identifies and helps manage the function, it’s a bit easier to wrap your head around:

VSCode

Another thing to consider coming from Java is that Javascript is a loosely typed language. This is where your debugger can really help you again. The meta-information that goes into the values you are watching will tell you exactly what kind of object you are dealing with.  

If you really can’t take the loose typing, though, be aware that Javascript does support a “strict” mode which will take things into account such as:

  • Safe variable assignment.
  • Restricting access to the global context.
  • Defining duplicate properties in an object.

You can add “use strict” to the top of your code to turn this mode on for your entire script, or, you can even embed it in single functions to scope strict checking to those functions.

Finally, like any other language, there is no replacement for mindful, comprehensive exception checking. Be aware of the calculations you are performing and don’t take for granted that all calculations will be valid or that data will be properly converted by the time it makes it to your code. Well written code will plan for the unexpected and use try/catch blocks to plan contingent logic.

IDE Considerations

Like any programming language you may be used to, Node.js can be 100% programmed using nothing but patience, caffeine, and VIM. However, most veteran developers have come to appreciate the benefits of a well-designed IDE.  

Microsoft’s cross-platform open source Visual Studio Code (VSCode) is my personal IDE of choice when it comes to Node.js. Build and run configurations are very easy to maintain, the code debugger is seamless and easy to use, and the interface itself is lightweight, efficient, and visually pleasing.

Most of the editor’s configuration is done in JSON and so use with any Javascript-derived framework including Node.js will offer a consistent experience across the board. All expected SCM interoperability such as Git, etc, is implemented well.

javascript node.js

This is all in addition to the wealth of extensions and plugins provided by the Node.js community at large:

IDE Considerations

This is by no means your only option, with plenty of IDEs to choose from, including offerings from Java-friendly organizations like Eclipse and IntelliJ.

Managing Dependencies in Node.Js


Those who have grown accustomed to Java build management tools such as Maven and Gradle will be pleased to know that an extensive package manager called ‘npm’ exists for Node.js and can be easily invoked to deal with dependencies.

Node.js applications that have dependencies, per good practice, should ship with a build description file called package.json. This file will contain information about the build itself including meta data like the title and version, and dependency information.

{
  "name": "helloworld",
  "version": "1.0.0",
  "description": "Hello World!",
  "main": "hello.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Justin Reock",
  "license": "GPL-3.0-or-later"
}

When deploying a new Node.js application, it is common to only distribute the package.json file and the bespoke source code for the application. The ‘npm install’ command can be run from the root installation folder of the app and all of the prescribed dependencies for the application will be downloaded and aligned.

Note that it is trivial to build local, private repositories for Node.js, similar to what you may be used to with tools such as Artifactory and Sonatype Nexus. Npm even allows you to build semantic versioning into your build processes, allowing for further automation of things like automatic dependency patching of non-breaking releases. Paired with new methodologies for achieving constant feedback loops and canary releases, this can make for incredibly robust, safe and self-updating dependency relationships.

All Node.js developers should originate their Node.js apps with a call to ‘npm init’ which will create a starter package.json file after a few prompts.  From there, the ‘npm install’ directive can be used to add new dependencies which will be immediately available for coding against.

nodejs

Node.js Deserves a Place in the Enterprise

I hope that this has helped to illuminate for you that moving to Node.js doesn’t mean eschewing all of the familiar concepts that veteran coders have come to appreciate. Though different in many respects, Node.js provides ways to address the programming styles of both new and veteran developers.  And don’t forget that training and support from a group like OpenLogic can be a great way to kickstart your organizations use of this popular and exciting platform!

Get real, consultative support from one of our Enterprise Architects, helping you solve real-world challenges with open source. Try OpenLogic Free!

TRY OPENLOGIC FREE