👩‍💻Building a RESTful API with Node.js

Alessandro Marchesin
7 min readApr 21, 2023

After understanding the story about Node, in the following lines, we will explore how to create a RESTful API to effectively manage any interaction request from a user to store, get and update data.

In particular, we will collect website checks: we want to create a list of websites with information regarding whether they’re up or down, their protocol, and other attributes. This data will not be available to everyone but just to authenticated users: we will then put in place an authentication barrier, store safe passwords, and generate session tokens.

Of course, website checks are just a proxy to teach you how to manage any kind of that: we are not really into knowing about website status, but we are just using them to learn how to structure a Node app, so then you will be able to store anything you want.

Let’s start coding! The repository can be found on GitHub.

How is a standard node.js app composed?

A standard Node.js app is typically composed of three main sections:

  1. Dependencies: This section imports all the necessary modules and packages the application requires. For example, it might include packages for handling HTTP requests, working with databases, or implementing authentication.
  2. Support code: The main code will handle the application logic. It might include functions for authenticating users, querying a database, or processing HTTP requests.
  3. Server setup: This section creates the server and defines how it will handle incoming requests. It might include code for listening on a specific port, defining routes for different requests, and setting up middleware for handling authentication, logging, or other functionality.
  4. Module exports: to make components available to other pieces in the folder.

For instance, here below, you can find the code of the app’s main file.

/*
* Primary file for API
*
*/

// Dependencies
var server = require('./lib/server');
var workers = require('./lib/workers');

// Declare the app
var app = {};

// Init function
app.init = function(){

// Start the server
server.init();

// Start the workers
workers.init();
};

// Self executing
app.init();

// Export the app
module.exports = app;

Overall, the structure of a Node.js app will vary depending on the project’s specific requirements, but this basic three-part structure is a good starting point for most applications. In addition to the three main sections, a Node.js app can have other components, such as models, views, and controllers, depending on the architecture pattern used (such as MVC or MVP).

For instance, in our example, we have the following folders

Our project is composed of the following sections.

  • .data folder is where we are physically storing the .json file. Of course, keeping on your machine is an option, but remember all the online options available.
  • https Folder. We hold the certificates that enable your app to be HTTP-proof.
  • lib Folder: here, you can find methods libraries that will be used multiple times during our execution. As you know, it’s essential to avoid copying and pasting and instead generate methods accepting our preferred parameters.
  • index.js: • the first file at server startup that we use as a bridge to call all the other functions in the project to handle users’ requests correctly.

“Support code”: main methods and objects created ad-hoc to support operations

Let’s go through the file in lib folder. I would advise following along with the repository on a side to understand theory and practice altogether.

  • config.js contains settings that are called when we start the server, i.e. when we write on our terminal node index.js. It contains two environments with different parameters such as ports to use, environment names, Twilio credentials in case you want to send SMS notifications, et cetera.
  • data.js contains five methods that let you manage your local storage. They are create, read, update, delete and list. They leverage JSON parsing and always return a callback.
  • handlers.js contains the management of the response for each request raised. It’s first checked whether the request is valid and then rerouted. Example: if I make a get request to user, handlers.users is checking whether the method is valid and then re-routing to handlers._users.method(). handlers._users.method() then check whether the payload is valid and exploit data manipulation methods mentioned above to store/retrieve/manipulate information and give a callback to the user.
  • helpers.js contains a series of methods he exploits to parse JSON files, create random strings to avoid storing passwords and create SMS notifications through Twilio.
  • logs.js has some similarities with data.js, but is more focused on log manipulation. We have put a series of methods that helps us append, list, compress, and decompress logs. We do that because you may want to save space by keeping them compressed.
  • server.js, • together with workers (below), is our main file. It is useful to create a server, handle the query string and redirect to the correct handler. When the request is fine, the status
  • workers.js starts right after server.js and helps validate data in the string. It also handles timeouts, errors, alerts and logs.

Un giro completo

As it happens with cards game, let’s try to play to understand all those information: We start everything with Node.js. Now the server is up and running, using the parameters we have in config.info. It will start listening. We can make an API call, such as in an app like Postman and make a request.

The request will be parsed, building an object called requestDetails, composed of the protocol, hostname, method, path and timeout. The server will then distribute data to the correct handler.

How to create a user?

For instance, if we make a POST request to users (handlers._users.post()at line 43, we will go through creating a new user. Data required will be a first name, last name, phone, password and terms of service agreement, as in an ordinary registration.

  • After verifying that inputs are reasonable, we will check whether there’s an error using read methods because we can’t find that user (using the phone as the primary key, which may not be the best practice).
  • We’ll then exploit the hash method to generate a token from the password and create a user record from that with the method _data.create().

How to authenticate a user?

Another route is POST for tokens, which we use to “log in” to the user. A token is generated to grant that the user is authenticated. The needed data is the phone and password.

  • After checking inputs (like, is the phone a string? Is the password not null? Et cetera, we check whether the hashed password equals the one stored for the user.
  • In a positive case, a new token instantiation is generated, and its expiration date is set to the next hour (remember to handle milliseconds, Date.now() + 1000 * 60 * 60)
  • After that, a token is created by the write method we already know very well.

How to check whether a website is down?

Let’s finally look at how to check a website from the one stored. The only required data is the id of the check.

After checking that the id is a valid input, we read whether there’s any proper check. If so, we’ll exploit handlers._tokens.verifyToken() to verify that the user has an active token. If so, data is returned. For instance, we know that http://google.com is a live website because a user created the check.

Final note

In the article, we have provided a comprehensive guide on creating a RESTful API using Node.js, which can be utilized for managing user requests for storing, getting, and updating data. The guide covers the basic structure of a Node.js app and the different components that can be included. It also provides an overview of an example project, a RESTful API for managing website checks. The guide consists of a folder structure for the project and a description of its different folders and files. It also covers the various methods and objects created to support operations, such as data.js, handlers.js, and logs.js. Lastly, the guide explains how to create a user, authenticate a user, and check whether a website is down using the API.

Yes, we scratched the surface regarding details: we could have dived deeper on any line of code, but the length would have been a problem then. Check the unique masterclass I have taken inspiration from to build this article and learn more! Now what are we missing? A web interface! Stay tuned for news!

--

--