THE BEGINNER’S GUIDE: Understanding Node.js & Express.js fundamentals

Linda Vivah
Jul 28, 2017 · 12 min read

If you are wondering what Node.js is and what makes it so great, you came to the right place.

I will start out by (1)briefly introducing Node.js, (2) building a ‘hello world’ app, and then (3) explaining the concepts within the app to get a better understanding of Node.js fundamentals.

(4) I will also touch base on what Express is and (5) walk you through building a sample demo express app.

INTRODUCTION TO NODE.JS

What is Node.js?

In simple terms, it’s a JavaScript free and open source cross-platform for server-side programming that allows users to build network applications quickly.

Installing Node.js

If you’re using OS X or Windows, the best way to install Node.js is to use one of the installers from the Node.js download page. If you’re using Linux, you can use the installer, or you can check NodeSource’s binary distributions to see whether or not there’s a more recent version that works with your system.

Test: Run node -v. The version should be higher than v0.10.32.

***If you are stuck, check out these docs for guidance.

Now that we have it installed, let’s get right to it!

Demo “Hello World” Node app

One of the most common uses for node is running your server. Let’s create your first Node.js HTTP server.

Step 1: Go to terminal & create a folder called “Hello World”

mkdir hello-world

Step 2: Go inside the project & create a file in the root called app.js

cd hello-world
touch app.js

Step 3: Paste this in your app.js file:

const http = require('http');var server = http.createServer(function (request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.end("Hello World\n");
});
server.listen(4000);
  • This http variable contains a function called createServer. This is all you need to do to create an http server.
  • Line 2, 3, 4: This function is a callback → We use the response variable that’s passed in to the callback to write the head and pass in the content type and we end that response with hello world. → This function returns an object that we are going to put in to our server variable and this object is going to have another function called “listen” →
  • Line 5: the minute that we call listen that’s when our server is going to start running as we listen to this port. You can choose any port.
  • By default, HTTP uses port80 but ideally you should specify a port.

Step 4: You can then run your server by going to your terminal and typing:

node app.js

Step 5: Now go to your port…

http://localhost:4000/

You should see “Hello World”. :)

Congratulations, you now have a server running!

What makes Node.js so great?

  1. It’s a JavaScript runtime built on Chrome’s V8 JavaScript engine.
    - Both Node and the JS that is executed inside of your browser are running on the same engine → It’s an open source engine that takes JS code and compiles it to much faster machine code → this is what makes Node.js so fast!
  2. Uses an event-driven, non-blocking I/O model that makes it light weight & efficient
    - What is event-driven programming? Basically, it’s a different way of thinking about your program flow. The flow of your program is defined by the events that are taking place. (see below for more details)
    - What is I/O? Input/Output
    - Difference between blocking & non-blocking software development Blocking methods execute synchronously and non-blocking methods execute asynchronously. (see below for more details)
  3. Node.js’ package ecosystem, npm, is the largest ecosystem if open source libraries in the world (see below for more details)

Let’s dive in to what all this means in more detail. The following are a few concepts that we need to understand:

What is Event Driven Programming?

Event Driven Programming is a computer programming paradigm in which control flow of the program is determined by the occurrence of events. These events are monitored by code known as an event listener that, if it detects that its assigned event has occurred, runs an event “handler”, typically a callback function or method. This handler deals with the event by responding to it with program code.

If you look back at the server function, the response only runs once we get a request — that’s event driven programming:

....
var server = http.createServer(function (request, response) {
....

It doesn’t just happen automatically. There is a process that happens and you have to wait for that.

Node Event Loop

So the next question you might be asking is how do we check for a request? How do we know when something is happening? How do we guarantee that in our code?

Answer: Node provides the event loop as part of the language. The minute that you call Node you don’t have to call a start function to start a loop that’s waiting for events. You literally just put in your script and the loop starts the minute that you start Node and it doesn’t end until the last callback is called so what that means is that if you are creating an http server, the end of that callback will just never arrive because you will always be waiting for an http request to come in and as a result your program won’t shut down until you tell it to shut down.

Blocking I/O

Since the Node event loop is run under a single thread calling something like sleep() makes everything halt — you are blocking the event loop.

Things like reading a file can also block an event loop. The event will be blocked until the entire file is read. This might not be optimal. Imagine you have a long file? it would stop all the other requests when that one is being handled.

const fs = require(‘fs’);var contents = fs.readFileSync('package.json').toString();
console.log(contents);

***When running Node you want to have your application as asynchronous as possible since it is constantly running an event loop. Even things like reading a file can be run asynchronously. The above snippet of code is synchronous. Let’s see how we can improve it to avoid ‘blocking’…

Asynchronous version:

const fs = require(‘fs’);fs.readFile('package.json', function (err, buf){
console.log(buf.toString());
});

In the above snippet, I am passing a callback as opposed to having it freeze while it reads the file. The function is a bit different than the synchronous version we had initially. By passing a callback, the minute it reads a chunk of that file it will execute the callback and move on, letting other events run. This solves the ‘blocking’ issue.

GOAL: ***In event driven programming your goal is to get the events timing tied as closely to the actual data flow. You want it to pretty much deal with the chunk of data you need.

Callback Style Programming

We have mentioned callbacks a lot — It is important to understand this concept: The event loops result in callback type programming. In simple terms it’s where you end up splitting your program in to smaller & smaller chunks until each chunk is mapped to operation with data.

This kind of program caused ‘callback insanity’ → many nested callbacks. It makes it not as readable and manageable. Most importantly, it makes it harder to debug. So how should we handle it??

Promises style programming!!!

Promises

What is Promises stye programming?

When a function will return a promise object that will return something in the future. It promises that it will do something for you. You can also chain promises together and it really helps simplify your code.

promise.then(function(result) {
console.log(result); // "Stuff worked!"
}, function(err) {
console.log(err); // Error: "It broke"
});

then() takes two arguments, a callback for a success case, and another for the failure case

Chaining: then() isn't the end of the story, you can chain then together to transform values or run additional async actions one after another.

promise.then(function(val) {
console.log(val); // 1
return val + 4;
}).then(function(val) {
console.log(val); // 5
})

Event Emitters

Ok so we reviewed some important concepts but now what happens when we want to pull data from the server that we built? Well, we would have to change it up a bit and use ‘event emitters’.

What are Event Emitters?

An Event emitter, as it sounds, is just something that triggers an event to which anyone can listen. Different libraries offer different implementations and for different purposes, but the basic idea is to provide a framework for issuing events and subscribing to them.

In node.js an event can be described simply as a string with a corresponding callback. An event can be “emitted” (or in other words, the corresponding callback be called) multiple times or you can choose to only listen for the first time it is emitted.

Let’s say your node.js app is connected to an office automation system…

var office = require('./office');  office.door.on('knock', function() {     
/// do something
});

The ‘on’ function pretty much says whenever I get a data event, run this function. As a client of this object you start listening to “knock” events by using the .on method & passing in a function that gets called whenever an event with that specific name happens

The on or addListener method (basically the subscription method) allows you to choose the event to watch for and the callback to be called.

The emit method (the publish method), on the other hand, allows you to "emit" an event, which causes all callbacks registered to the event to 'fire', (get called).

// get the reference of EventEmitter class of events module
const events = require('events');
//create an object of EventEmitter class by using above reference
const em = new events.EventEmitter();
// register a listener for the 'knock' event
em.on('knock', function (data) {
console.log('Received the knock event: ' + data);
});
// trigger an event called 'knock'
em.emit('knock', "who's there?");
  • In NodeJs, any object that emits an event is an instance of the EventEmitter class
  • If you run this script the response in terminal will be:
Received the knock event: who’s there?

Node Package Manager (NPM)

What is NPM?
It is the official package manager for Node and is bundled & installed automatically with the environment.

Here is how you would install a specific package via terminal:

npm install — save package_name
npm update

**by writing ‘save’ it will save the package in to your package.json folder which handles your dependencies.

What is package.json?

{
“name”: “Node101”,
“version”: “0.0.0”,
“description”: “Sample Code”,
“main”: “hello_world.js”,
“author”: {
“name”: “Linda Haviv”,
“email”: “”
}
}

There are lots of great modules on NPM:

Popular NPM modules:- 7053 underscore
- 6458 async
- 5591 request
- 4931 lodash
- 3630 commander
- 3543 express
- 2708 yargs
- 2634 coffee-script

How does it work?
The best way to manage locally installed npm packages is to create apackage.json file.

A package.json file affords you a lot of great things:

  1. It serves as documentation for what packages your project depends on.
  2. It allows you to specify the versions of a package that your project can use using semantic versioning rules.
  3. Makes your build reproducible which means that its way easier to share with other developers.

***(source: npmjs docs)***

In general, Node is a great tool to quickly get an api up and running

Note: The first thing you do when you get any kind of Node project is that you navigate to the directory that it’s in and in terminal write:

npm install

This command will look at everything you have in your package.json file and it will install all of those things

How to use Modules in Node.js?

Now that we listed some popular modules, you might be wondering how to use them in your projects. To do that, we need to use a function in Node called require. The demo server we previously built used the built-in require module.

const http = require(‘http’);
.....

Require will let us do 3 things:

  1. load in modules that come with Node.js — example: http module, FS module
  2. load in third party libraries that allows us to write less code — example: express.js
  3. require our very own files. This will allow us to break up our application to multiple smaller files which is essential for building real-world apps.

INTRODUCTION TO EXPRESS.JS

What is Express?

It’s a web framework that let’s you structure a web application to handle multiple different http requests at a specific url.

Express is a minimal, open source and flexible Node.js web app framework designed to make developing websites, web apps, & API’s much easier.

Why use Express?

Express helps you respond to requests with route support so that you may write responses to specific URLs

Supports multiple templating engines to simplify generating HTML.

The nice thing about it is it’s very simple and it’s open-source

Installing & using Express

You can get it through NPM

npm install express

Demo: Creating a simple Rest api

  • A router maps HTTP requests to a callback
  • HTTP requests can be sent as GET/POST/PUT/DELETE, etc..
  • URLs describe the location targeted

Basic express app:

Step 1: Go to terminal & create a folder called “Hello World”

mkdir node-web-server

Step 2: Go inside the project & generate the package.json file using npm init

cd node-web-server
npm init

**use the default values just by pressing enter through all of the options

Step 3: Install express

npm install express --save

Step 4: create a file called server.js in the root

touch server.js

**this is where we will configure all our routes.

Step 5: Paste the following code in your server.js file:

const express = require('express');var app = express();app.get('/', (req, res) => {
res.send('Hello Express')
});
app.listen(process.env.PORT || 3000)

Line 1: You can think of require as a need to import something. You can instantiate it at the top of your file.
Line 2: We are creating the express app by setting it to the app variable.
Line 3: .get is saying that when it gets that route it should give the response that is specified in the function. It takes in 2 arguments: (1) the url (2) the function that tells express what to send back to the person making the request.
Line 5: .listen is going to bind the application to the port on our machine.

When you run NPM install and save the dependencies in the terminal, they get added in to the package.json file:

{
“name”: “node-web-server”,
“version”: “0.0.0”,
“description”: “Sample Code”,
“main”: “index.js”,
“author”: {
“name”: “Linda Haviv”,
“email”: “”
},
"dependencies": {
"express": "4.15.3",
"jade": "*",
"underscore": "^1.7.0"
}
}
  • The syntax it uses is semantic versioning, which pretty much means you can specify which version of the dependency you would like.
  • A star symbol (*) means it can be any version, whichever is the latest one.
  • A carrot symbol ^ prior to the version means I want that version or anything newer.

To run the application install nodemon & type the following in terminal:

npm install -g nodemon
nodemon server.js

***you can use ‘nodemon’ instead of ‘node’ when running your app locally. Nodemon monitors your app for any changes & automatically restarts your application; With the ‘node’ command, you have to do that manually.

Step 6: Go to your browser and go to port 3000

http://localhost:3000/

You should see “Hello Express”. :)

Templating

What is middleware?

You might hear the term middleware thrown around a lot but what is it in the context of Express.js? Middleware is any number of functions that are invoked by the Express.js routing layer before your final request handler is, and thus sits in the middle between a raw request and the final intended route. It basically lets you configure how your express application works.

In order to add middleware we will do the following:

Step 7: Go to terminal and in the root create a folder called Public and add an html file inside

mkdir public
cd public
touch test.html

** the public folder, as it sounds, is public and is where you put static assets that can be viewed by everybody

Step 8: Paste the following code in the test.html file

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test Page</title>
</head>
<body>
<h1>Test Page</h1>
<p>Some text here</p>
</body>
</html>

**the goal will be to serve up this page without having to manually configure it

Step 9: Let’s add some middleware by going to the server.js file & adding the following code:

***app.use takes the middleware function you want to use

const express = require('express');var app = express();app.use(express.static(__dirname + '/public'));app.get('/', (req, res) => {
res.send('Hello Express')
});
app.listen(process.env.PORT || 3000)

Step 10: Go to the terminal & run nodemon

nodemon server.js

Step 11: Go to localhost 3000

http://localhost:3000/test.html

***you should see the following:

localhost:3000/test.html

***For dynamic templating look into handlebars***

Sample Structure of a Node Express app

Node and Express don’t come with a strict file and folder structure.

  • controllers/ — defines your app routes and their logic. You main route might be index.js but you might also have a route called for example ‘/user’ so you might want to make a JS file that just handles that.
  • helpers/ — code and functionality to be shared by different parts of the project
  • middlewares/ — Express middlewares which process the incoming requests before handling them down to the routes
  • models/ — represents data, implements business logic and handles storage
  • public/ — contains all static files like images, styles and javascript
  • views/ — provides templates which are rendered and served by your routes
  • tests/ — tests everything which is in the other folders
  • app.js — initializes the app and glues everything together
  • package.json — remembers all packages that your app depends on and their versions

Linda Vivah

Written by

Web Developer | Tech & Lifestyle Blogger | Founder CodingCrystals.com | IG @LindaVivah

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade