Beginners guide to Node JS.
This article is going to be a simple and beginners perspective on Node JS helpings everyone to learn about the technology.
Table of contents
- Introduction
- Difference between Browser & Node JS Runtime Environments.
- How much JS do you need to get started with Node Js?
- Steps to get started with Node JS
- Importance of Node JS.
- Writing web apps with NodeJs.
- Getting used to callbacks in Node.
- Routing in NodeJs.
- Routing with Express.
- Networking with NodeJs sockets.
- Conclusion
Learning to code has been one of my best decisions in life to date, and choosing JavaScript as the language has never been any tougher. Starting a server in Node is easy if you follow the documentation but it takes a deep knowledge of the language to build web apps that scale. So let's get started.
Introduction
Node.js is an open-source and cross-platform JavaScript runtime environment.
Open-Source: This means that the source code for Node.js is publicly available. And it's maintained by contributors from all over the world.
Cross-platform: This means Node.js is not dependent on any operating system software. It can work on Linux, macOS, or Windows.
Node.js is a JavaScript runtime environment: When you write JavaScript code in your text editor, that code cannot perform any task unless you execute (or run) it. And to run your code, you need a runtime environment.
Browsers like Chrome and Firefox have runtime environments. That is why they can run JavaScript code. Before Node.js was created, JavaScript could only run in a browser. And it was used to build only front-end applications.
Node.js provides a runtime environment outside of the browser. It's also built on the Chrome V8 JavaScript engine. This makes it possible to build back-end applications using the same JavaScript programming language you may be familiar with.
Before Node JS
Previously, web apps were written in a client/server model where the client would demand resources from the server and the server would respond with the resources. The server only responded when the client requested and would close the connection after each response.
This pattern is efficient because every request to the server takes time and resources(memory, CPU etc). So, it's wiser to close a connection after serving the requested asset so the server could respond to other requests too.
So how do servers like these respond to millions of requests coming in at the same time? If you asked this question, you understand that it wouldn’t be nice if requests to servers would be delayed till all other requests were responded to.
Let's imagine visiting a ticket booking website and you were told to wait for 5 minutes, for thousands of people requesting before you. There has to be a way to run thousands or at least hundred of requests at once. Now here comes Threads.
Threads are a way for systems to run multiple operations concurrently. So every request would open a new thread, and every thread had all it required to run the same code to completion.
But this system has a downside. It would get to a point where there are a lot of requests and starting up new threads would consume a whole lot of memory and system resources.
But it’s also a good thing that immediately the server responds to the browser, the connection is closed and all resources (memory etc) are retrieved.
A benefit of this system is that it excels at CPU-intensive applications. CPU-intensive operations require a lot of logic and take more time to compute. Since every new request is handled by a new thread, it takes serious work off the main thread, therefore, making the system faster and able to perform important computations.
It’s quite efficient because each operation executes code off the main thread. But could things get better?
Use case
In Node JS, while the file system is reading the file, Node uses idle time to handle other requests. When the file system is done, it's smart enough to tell Node to come to take resources and send them to the browser. This is possible of Node's Event Loop.
An event loop is a program that waits for events and dispatches them when they happen. Another important fact is that JavaScript is a single thread and so is Node.
Unlike other languages that require a new thread or process for every single request, Node JS takes all requests and then delegates most of the work to other system workers.
Difference between Browser & Node JS Runtime Environments.
Both the browser and Node.js are capable of executing JavaScript code. But there are some key differences that you need to know. They include the following.
Access to DOM APIs
With the browser runtime, you can access the Document Object Model (DOM). And you can perform all the DOM operations. But Node.js does not have access to the DOM.
Node.js exposes almost all the system resources to your programs. This means you can interact with the operating system, access the file systems, and read and write to the files. But, you do not have access to operating systems and file systems from the browser.
Control over Run-time versions
With Node.js, you can choose which version to run your server-side application on. As a result, you can use modern JavaScript features without worrying about any version-specific inconsistencies.
Contrast this to the browser runtime environment. As a developer, you have no control over the version of browsers your clients use to access your app.
Loading Modules
Node.js offers out-of-the-box support for CommonJS and ES modules. You can load modules using the require
keyword (CommonJS syntax) and the import
keyword (ES syntax).
Some modern browsers support ES modules. This means you can use import
ES modules. But you will still need to create bundles to cater to older browsers that do not support ES modules.
How much JS do you need to get started with Node Js?
If you are an absolute beginner to JavaScript, I recommend that you start with the basics. Refer to my Blog.
Become familiar with basic JavaScript concepts first. Then, you can move on to learning to build server-side applications with Node.js.
There's no way you'll ever exhaust all there is to learn about JavaScript. So, how to determine when you know enough JavaScript to get started with Node.js?
The Nodejs.dev documentation provides a list of JavaScript topics to learn before diving deep into Node.js.
Once you have a grasp of JavaScript basics, then you can get started with Node.js
Steps to get started with Node JS
Let's see how you can create your first Node.js application. This section will show you how to run Node.js scripts from the command line.
How to download and install Node.js
First, you need to download and install Node.js. There are different ways you can do that. If you are a beginner, I would suggest that you download Node.js from the official website.
Official packages are available on the website for all major platforms (Windows, macOS, and Linux). Download and install the appropriate package for your system.
How to check the Node.js version
To check the Node.js version, run the command node --version
in your terminal.
If the installation was successful, you will see the version of Node.js you installed.
How to run Node.js from the command line
Let's build a simple Hello World
app.
Create a new project folder. You can call it my-project.
Open the project in your code editor. Inside the folder, create an app.js
file.
Add the following code to app.js
As you can see, this is JavaScript code.
You can run the script in the command line by running the command node <fileName>
. In this case, the file name is app.js
.
Run the following command in your terminal to execute the Hello world.
program:
node app.js
You should see the string "Hello world." logged in your terminal like so.
Congratulations! You just ran your first Node.js application.
Importance of Node JS.
Here are some reasons why developers should consider learning Node.js
It allows developers to write JS on both the client and server.
Node is open-sourced and is actively maintained by developers all over the world having a vibrant community.
It's built on top of Chrome's V8 engine.
Huge demand in the market.
The NPM Library
The NPM library is one of the excellent resources that comes with Node.js.
The library contains a registry of over a million packages. A package is a reusable piece of code.
You can create a package for a recurring task or problem and share the code with others via the registry.
You can also download packages that others have shared. For many tasks that developers perform regularly, there are packages available for that.
Writing web apps with NodeJs.
Writing web apps with Node involves writing event handlers that get called when certain Node events occur. Let’s see an example.
Create a new folder, and cd into the folder with your terminal or command prompt.
Do an
npm init,
and hit enter till you successfully create apackage.json
file in the root of the folder.Create a
server.js
file in the root folder, copy and paste the code below.
4. In the command prompt, type in node server.js
and hit enter. You’ll see something similar to this.
node server.js
//Node server started at port 3000
Open your browser and hit localhost:3000. You should see a Hello world
message.
On the first line, we required the http
module. The module provides an interface to deal with HTTP operations, which we call the createServer()
method which well, creates a server.
Secondly, we attach an event handler for requests
on the server object. The on method takes a second argument which is a callback. The callback takes two objects as arguments. The request
and response
objects which have information about the incoming request and outgoing responses.
We could also let Node do some of the work for us.
Here, we just pass a callback to the createServer(), and Node adds the request
event handler for us. We are only concerned with the request
and response
object at this point.
We use the response.writeHead()
to attach some headers to the server’s response (status code and content type), response.write()
writes to the web page. Then we use the response.end()
to close the response to the server.
Lastly, we tell the server to listen at a port (3000). So we can at least see a demo of our web app while developing it on our local machines. (localhost:3000). The listen method takes a callback as the second argument. This callback fires immediately after the server start.
Getting used to callbacks in Node.
Node is a single-threaded event environment, meaning everything responds to events. Callbacks are functions that are passed to other functions as arguments and are called when an event happens.
Our example can further be written as.
makeServer
here is a callback, since functions are first-class objects in JavaScript, they can be passed into variables and then other functions.
If you’re not used to JavaScript, you might need some time to get used to event programming.
If you start writing some serious JavaScript code, you might get into trouble with callback hell. Where your code becomes hard to read because there’re a lot of functions nested deeply. When this happens, you might want to find more advanced and efficient ways to replace callbacks. Look into promises.
Routing in NodeJs.
A server stores lots of files, when browsers request, they tell the server what they are looking for. The server responds accordingly by giving them the files they ask for. This is called Routing
.
In NodeJs, we need to manually define our routes. It’s no big deal, here’s how to do a basic one.
Paste this code in your server.js file, navigate to it, and run it with node server.js
head to your browser hit localhost:3000 and localhost:3000/about,. Try doing it with something like localhost:3000/something-else. Our error page right?
While this may satisfy our immediate need of starting a server, it’s crazy to do this for every web page on your server. Nobody does this actually, but it’s just to give you an idea of how things work.
If you observed, we required another module; url
. It provides us with an easy way to work with urls
The .parse()
method takes the URL as an argument and breaks it into protocol
, host
path
and querystring
etc. If you don’t get that part, it’s alright.
Let’s take for example the URL.
So when we do url.parse(request.url).pathname
, it gives us the pathname or the URL which is primarily what we use to route requests. But things can get easier though.
Routing with Express.
If you’ve done some underground research, you must have heard about Express. It’s a NodeJs framework for easily building web apps and APIs. Since you want to write NodeJs apps, you’ll need Express too. It makes everything easier. You’ll see what I mean.
In your terminal or command line, navigate to your root folder, punch npm install express --save
. This installs the express package. To make it available in our program, we require it.
const express = require('express');
Now, this looks clean, right? I believe you might be getting tuned already. After importing the express module, we called it a function. This begins our server journey.
Next, we try to set the port with server.set()
. process.env.PORT
gets the environment port the app is running on and somehow, if it’s not available, we default it to 3000.
If you observed the code above, routing in Express follows a pattern.
server.VERB('route',callback);
VERB here is any of the GET, POST etc, pathname
is a string that gets appended to the domain and the callback is any function we want to fire when the requests come in.
There’s one more thing.
server.use(callback);
Whenever you see a .use()
method in express, it’s called a middleware
. Middlewares are functions that do some HTTP heavy lifting for us. In the code above, the middleware is an error-handling one.
Finally, we do our normal server.listen()
remember?
This is what routing looks like in NodeJs applications. Next, we delve into databases in Node.
Networking with NodeJs sockets.
A computer network is a connection of computers to share and receive information. To do networking in NodeJs, we require the net
module.
const net = require('net');
In Transmission Control Protocol (TCP), there must be two endpoints; one endpoint(computer) binds to a numbered port while the other connects to the port.
If you don’t understand it, take this analogy.
Imagine your cell phone. Once you buy a sim, you get assigned a number and you bind to that number. When your friends want to call you, they connect to your number. You are one endpoint and your caller is another.
I’m sure you understand now.
To cement this knowledge, we’re going to make a program that watches a file and informs connected clients when the file changes. Let’s dive right in.
Create a folder, call it
node-network
.Create three files,
filewatcher.js
,subject.txt
, andclient.js
. Put this intofilewatcher.js
.
3. Next we should provide a file to watch. Put this into subject.txt
and be sure to save it.
Hello world, I'm gonna change
4. Next, let's create our client. Put this into client.js
.
const net = require('net');
let client = net.connect({port:3000});client.on('data',(data)=>{
console.log(data.toString());
});
5. We’ll need two terminals. In the first one, we run the filename.js
with the name of the file to watch like so.
Note: The lines that begin with //
are not to be typed, they are additional information.
//the subject.txt will get stored in our filename variablenode filewatcher.js subject.txt//listening for subscribers
On the other terminal, we’ll run client.js
.
node client.js//watching subject.txt for file changes.
Now go ahead and change subject.txt
. Make sure to save the changes. Take a look at the client.js
terminal and notice the additional line.
//subject.txt has changed.
One major characteristic of a network is that many clients can connect at the same time. Start up another command line, navigate to client.js
run node client.js
and change the subject.txt
file again (don’t forget to save).
Don’t worry if you don’t understand, let’s go over it together.
Our filewatcher.js
does three things
creates a server to send messages to many clients.
net.createServer()
Tell the server that a client connected, also tells the client that there’s a file being watched.
console.log()
andconnection.write()
.Finally watches the file with the
watcher
variable and closes it when the client disconnects. Here’sfilewatcher.js
again.
We require
two modules, fs
and net
for reading and writing files and doing network connections relatively. If you watch closely, you’ll notice the process.argv[2]
, process is a global variable that provides vital information about the NodeJs code running. argv[]
is an array of arguments. When we say argv[2]
, we refer to the third argument used to run the NodeJs code. In the command line, we would enter the name of the file we want to watch as third argument argv[2]
. Remember this?
node filewatcher.js subject.txt
We also have something pretty familiar; the net.createServer()
this function fires whenever a client connects to the port, it accepts a callback. The callback takes only one parameter which is the object that communicates to connecting clients.
The connection.write()
method sends data to any client connecting to port 3000. In this case, our connection
object. In this case, we tell the client that a file is being watched.
The watcher
contains a function that sends information to the client
that the watched file has changed. And when the client
closes the connection by exiting the process, the onclose
event fires and the event handler passes the message to the server and closes the watcher
.
//client.jsconst net = require('net'),
client = net.connect({port:3000});client.on('data',(data)=>{
console.log(data.toString());
});
client.js
is pretty straightforward, we require the net
module and connect it to port 3000. We then listen for the data event and log it to the console.
You should understand that whenever our filewatcher.js
does a connection.write()
, our client gets a data event.
This is just a scratch of the surface of how networks work. Primarily, one endpoint broadcasts messages when certain events occur and every client connected receives it as a data
event.
If you would love to go deeper into networking with Node, Here’s a post from the official NodeJs documentation; The net module. You might also want to read Building a Tcp service using Node.
Phew!, now that was a lot.
If you wish to write scalable web apps with NodeJs, you need to know more than just writing servers and routing with express.
Here are some books I recommend.
Web Development With Node and Express.
Conclusion
This article will give you an overview of what Node.js is. If you were not sure what Node.js is, I hope this article addressed your concerns and cleared your confusion.
Thanks for reading. And happy coding!