Building a Basic Todo List REST API in Node.js with Express

ACT
3,371 views

Open Source Your Knowledge, Become a Contributor

Technology knowledge has to be shared and made accessible for free. Join the movement.

Create Content
Next: Discover Express

General Introduction

Node.js is a server that makes able to run JavaScript code "Server Side". It is based on V8, the JavaScript engine used in Chrome, and uses some modules to help working with the filesystem, sockets, HTTP, etc.

In this tutorial we will get trough some of the main concepts of Node.js. To illustrate them, we will create a simple todo list web application.

Node.js Anatomy & Key concepts

Node.js Anatomy

NodeJS is composed of:

  • V8 a JavaScript engine
  • An EventLoop (using libuv)
  • Some Core modules that allows NodeJS to interact with the operating system such as
    • File System: filesystem module
    • Net: network module
    • HTTP: http module
    • Stream: stream module
    • ...

The core modules are defined within Node.js's source and are located in the /lib folder.

Core modules are always preferentially loaded if their identifier is passed to require(). For instance, require('http') will always return the built in HTTP module, even if there is a file by that name.

For more information, please visit: https://nodejs.org/api/

Event Loop & Non-Blocking Programming

At the heart of NodeJS stands an Event Loop.

The event loop is what allows Node.js to perform non-blocking I/O operations — despite the fact that JavaScript is single-threaded — by offloading operations to the system kernel whenever possible.

Since most modern kernels are multi-threaded, they can handle multiple operations executing in the background. When one of these operations completes, the kernel tells Node.js so that the appropriate callback may be added to the poll queue to eventually be executed. We'll explain this in further detail later in this topic.

More About Event Loop

The following diagram shows a simplified overview of the event loop's order of operations. Node.js EventLoop

Each phase has a FIFO queue of callbacks to execute. While each phase is special in its own way, generally, when the event loop enters a given phase, it will perform any operations specific to that phase, then execute callbacks in that phase's queue until the queue has been exhausted or the maximum number of callbacks has executed. When the queue has been exhausted or the callback limit is reached, the event loop will move to the next phase, and so on.

  • timers: this phase executes callbacks scheduled by setTimeout() and setInterval().
  • I/O callbacks: executes almost all callbacks with the exception of close callbacks, the ones scheduled by timers, and setImmediate().
  • idle, prepare: only used internally.
  • poll: retrieve new I/O events; node will block here when appropriate.
  • check: setImmediate() callbacks are invoked here.
  • close callbacks: e.g. socket.on('close', ...).

from https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/

Now that you have this concept in mind, we can start crafting the todo list application.

My First Hello World HTTP Server

To create a HTTP server with Node.js, we will use the 'http' module. To do so, we need first to call the require function. This function returns a reference to the module passed as argument.

Hello World Example in Node.js
1
2
3
4
5
6
7
8
9
10
11
const http = require('http');
const port = 9000;
const server = http.createServer((request, response) =>{
response.write('Hello World!');
response.end('\n'); // end of the response flow.
// the two lines can be merged as one:
// response.end('Hello, World!\n');
});
server.listen(port); // listening on 9000
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Introduction to HTTP Module

The http module allows you to create a HTTP Server using http.createServer([requestListener]).

This function takes a requestListener(request, response) function as parameter. This function will be executed when the 'request' event will be published by the server (meaning that a request is taken in charge by the server). The requestListener function has two parameters both created by the http.Server:

  • request is an http.IncomingMessage that can be used to access to the request informations such as

    • request.headers: Key-values pairs of headers names and values
    • request.method: the request method as a string
    • request.url: the requested url
  • response is a http.ServerResponse that offers some functionalities to craft the answer such as:

    response.write("hello world");
    
    response.setHeader('Content-Type', 'text/html');
    
    response.statusCode = 404;
    

After having setup the server, you can bind it to a port using the listen function.

Using HTTP Verbs

As you may know, HTTP is using some methods (also know as "verbs") such as GET, POST, PUT, DELETE. Each method represents a kind of actions that can be executed on a resource (~ something designed by an URI).

When a HTTP client (such as a web browser) makes a request this request has three main parts:

  • the request line that contains the method (a.k.a verb), the path and the HTTP version
  • the headers that provides information about the request
  • the message body

In Node.js, this informations are available in the request object. Some of this information can be easily retrieved:

  • request.method to retrieve the HTTP verb
  • request.url to retrieve the path
  • request.rawHeaders to retrieve an array of the headers
  • request.httpVersion to retrieve the HTTP version ...
Exercise: Check that the HTTP Verb Is "GET"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const http = require('http');
const port = 9000;
const server = http.createServer((request, response) =>{
if( ???TODO??? ){
response.end('Hello, World!\n');
}else{
// Doc: response.writeHead(statusCode[, statusMessage][, headers])
response.writeHead(405, 'Method Not Allowed');
response.end('This URI only support GET method\n');
}
});
server.listen(port); // listening on 9000
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Checking each HTTP verb in that way appears somewhat cubersome and could make the code hard to read. Let's move on a framework that will help us with that boilerplate code: the Express framework.

Open Source Your Knowledge: become a Contributor and help others learn. Create New Content