Setting up a REST API with Node.js and Express.js
Tags: node, express, restapi
Published: 2020-09-22 21:42:28

Hey there,

I will show you how to set up a Rest API with Node and Express. I hope you can learn something from this tutorial and I can learn something with your feedback.

###Requirements:
- Node installed ([Documentation](https://nodejs.org/en/download/package-manager/#installing-node-js-via-package-manager)).
- Yarn ([Documentation](https://classic.yarnpkg.com/en/docs/install/#arch-stable)).
- Insomnia ([Download](https://insomnia.rest/download/core/?)).
- Visual Studio Code ([Download](https://code.visualstudio.com/#alt-downloads)).

## Let's go!

![Alt text of image] (https://media.giphy.com/media/da75JuW2HHuBNqOHHE/giphy.gif)

## What is Rest?
> REST, or REpresentational State Transfer, is an architectural style for providing standards between computer systems on the web, making it easier for systems to communicate with each other. REST-compliant systems, often called RESTful systems, are characterized by how they are stateless and separate the concerns of client and server. We will go into what these terms mean and why they are beneficial characteristics for services on the Web.
[Reference.](https://www.codecademy.com/articles/what-is-rest)

## What is API?
> API is the acronym for Application Programming Interface, which is a software intermediary that allows two applications to talk to each other. Each time you use an app like Facebook, send an instant message or check the weather on your phone, you’re using an API.
[Reference.](https://www.mulesoft.com/resources/api/what-is-an-api)


##Starting the project:

The first step will be creating a folder to save our project.

```bash 
$ mkdir nodejs-express-setup
$ cd node-express-setup
```
Next step, we will create the package.

```bash 
$ yarn init -y
```
*I recommend you to use the flag -y if you do not want to answer the questions. This flag means you will accept to use the default options.* 

You can find more information about *yarn init* in [Yarn cli](https://yarnpkg.com/cli/init) or using the command line ``$ yarn --help init`` in your console.

Checking the folder "nodejs-express-setup" you will find a file named *package.json*, probably you are making this question...

![Alt text of image] (https://media.giphy.com/media/DUrdT2xEmJWbS/giphy.gif)

###What is package.json?

> The package.json file is kind of a manifest for your project. It can do a lot of things, completely unrelated. It's a central repository of configuration for tools, for example. It's also where npm and yarn store the names and versions for all the installed packages. 
[Reference.](https://nodejs.dev/learn/the-package-json-guide)

In addition, you can find some information and tips in [Yarn package-json](https://classic.yarnpkg.com/en/docs/package-json)

*I hope this information helps you to understand how works package.json.*

![Alt text of image] (https://media.giphy.com/media/5wWf7H89PisM6An8UAU/giphy.gif)

##Setting up the Express.js and nodemon with sucrase.

### Why do we need to install this framework?

Okay, let's start to imagine a mobile app or a web application, they will connect to an API every time these apps need to communicate with our back-end, this framework will make our work creating an API easier providing many HTTP utility methods.

Happy to listen to that... Right?

![Alt text of image] (https://media.giphy.com/media/yltGOJQBMBn7W/giphy.gif)

Now that you know the reason for installing this framework, we can proceed with the installation by running the command line below:

```bash 
$ yarn add express
```

We will install the *sucrase* and the *nodemon* libraries before proceeding with the *express.js* explanation.

```bash 
$ yarn add sucrase nodemon -D
```
*The flag -D means will install this library as a dev dependency. Packages are as a dev dependency are only needed for local development and testing. You can read more [here.](https://nodejs.dev/learn/npm-dependencies-and-devdependencies)*

We need to create a file named nodemon.json:
```bash 
$ touch nodemon.json
```
And then add the following lines to the nodemon.json:
```
  "execMap":{
      "js": "sucrase-node"
    }
```
This config will define our own default executables using the execMap. We are informing to *nodemon* to compile using *sucrase* before to run our code and it will happen every time a js file is executed.

### What is sucrase and nodemon?

> Sucrase is an alternative to Babel that allows super-fast development builds. Instead of compiling a large range of JS features to be able to work in Internet Explorer, Sucrase assumes that you're developing with a recent browser or recent Node.js version, so it focuses on compiling non-standard language extensions: JSX, TypeScript, and Flow. Because of this smaller scope, Sucrase can get away with an architecture that is much more performant but less extensible and maintainable.
[Reference.](https://github.com/alangpierce/sucrase#readme)

> Nodemon is a utility that will monitor for any changes in your source and automatically restart your server. Perfect for development.
[Reference.](https://nodemon.io/)

*Nodemon* will make our development faster than normal because it will restart the server automatically every time the code is saved.

With both libraries installed, we need to make one more change.

Edit the package.json adding the following lines:

```
  ...
  "license": "MIT",
  "scripts": {
    "dev": "nodemon src/server.js",
    "build": "sucrase ./src -d ./dist --transforms imports",
    "start": "node dist/server.js"
  },
  "dependencies": {
    ...
  },
  ...
```

*In this situation, scripts will make it easier to execute some longs commands.
For example, we can easily execute the command ``$ nodemon src/server.js`` with the command ``$ yarn dev``.*

Before executing this command line we need to create the *server.js.*

##Setting up the server.js

In this topic, we will start to learn how to use the *HTTP requests*. All the routes created will be in *server.js.* 

We need to create a folder named *src* and the file *server.js*:

```bash 
$ mkdir src && cd src && touch server.js
```

and then add the following lines in *server.js*:

```
import express from 'express';

class Server{
    constructor(){
        this.app = express();
        this.server();     
    }

    server(){
        this.app.listen(3333);
    }  
    
}


export default new Server();
```
In the code above, it has the attribute *"this.app"* to receive all the express methods and the *server* method to listen to the requests from the port 3333.


We can start the server now, you should go to your console to digit the command line below:

```bash 
$ yarn dev
```

In routes, we will create the routes *HTTP get, post, put, delete requests*. And also we need to add the array to test our requests.

```
import express from 'express';

const users = ['User01', 'User02'];

class Server{
    constructor(){
        this.app = express();
        this.server();
        this.routes();  
    }

    routes() {
    }

    server(){
        this.app.listen(3333);
    }  
    
}


export default new Server();
```

The first line will be added in *routes()* is the *express.json()*:

```
...
routes() {
   this.app.use(express.json());
}
...
```
The *express.json* is necessary to receive the *HTTP post* and *put requests* with a *JSON object*. You will understand better when we start to see the *HTTP post* and *put requests* examples. You can read more [here](https://expressjs.com/en/5x/api.html#express.json).

Before continuing, we need to install the *cors* library:

We will use this library for future tutorials using this project.

Add the following lines:

```
import express from 'express';
import cors from 'cors';

....
class Server{
    constructor(){
     ...
    }

    routes() {
       this.app.use(express.json());
       this.app.use(cors());
    }
...   
}

export default new Server();
```

#### What is cors?
> Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to tell a browser to let a web application running at one origin (domain) have permission to access selected resources from a server at a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, and port) than its own origin.
[Reference](https://developer.mozilla.org/pt-PT/docs/Web/HTTP/CORS)

This library is necessary to allow other applications to make requests to our API.

### Routes HTTP get, post, put, and delete requests:

#### Get:
We will start doing the *HTTP get request*. In this example, we will use a route without params or queries.

```
...
routes() {
   this.app.use(express.json());

   this.app.get('/users', (req, res) => {
            return res.json(users)
          })
}
...
```
*Open your browser and try to access the URL (http://localhost:3333/users) to receive an array with "'User01', 'User02'". The route is expecting to someone to access the path '/users' to return the array by res.json.*

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/9to3cc7qpdu2wuufoeh7.JPG)

Easy, right?

![Alt text of image] (https://media.giphy.com/media/y5yzypjVc9u3S/giphy-downsized.gif)

### How works the request and response objects?

#### Request:
> The *req* object represents the HTTP request and has properties for the request query string, parameters, body, HTTP headers, and so on.
[Reference.](http://expressjs.com/en/5x/api.html#req)

If we want to send an object in your request we can use *req.body* and if we want to pass some parameters we can use *req.params* or *req.query*. I will explain later about these two parameters.

#### Response:
> The *res* object represents the HTTP response that an Express app sends when it gets an HTTP request.
[Reference.](http://expressjs.com/en/5x/api.html#res)

The *response object* is basically responsible to provide the data or information every time the application receives an *HTTP request*. We could provide this data using *res.send()* or *res.json()*.

A brief explanation of the difference between *res.send()* and *res.json()*.

#### Res.send():
This method sets the content-type response header based on the parameter, for example, if it is sending an object, the header will set the content-type to application/JSON but if it is sending a string the content-type will be text/HTML.

You can find more information [here](http://expressjs.com/en/4x/api.html#res.send)

#### Res.json():
This method sets the content-type response header to application/JSON also if the parameter is non-object it will be converted to JSON.

You can find more information [here](http://expressjs.com/en/4x/api.html#res.json)

If you are passing an object or an array in the parameters you won't see any difference between *res.send()* and *res.json()* which in most cases is the kind of parameters we will pass to these methods.

I hope you understood the difference between the two methods. We can move forward to the next explanation.

![Alt text of image] (https://media.giphy.com/media/LKTTAzGboJGzC/giphy.gif)

In the last example, we did a route without params or query, in this example, we will do some routes with req.params and req.query.

#### Req.params:
This property is very useful when we want to get specific data inside of an array.

Below, we are using the req.params to find the user using the value from the index parameter.

```
...
routes() {
   this.app.use(express.json());

   this.app.get('/users/:index', (req, res) => {
        const { index } = req.params;

        return res.json(users[index])
      })
}
...
```
*Open your browser and try to access the URL (http://localhost:3333/users/1) to receive the string "User02". Basically the req.params receive the value through the index parameter and we will return the string based on the array index.*

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/xlsmux3ejwas6ywm4zyx.JPG)

For more information, you can read the [documentation](http://expressjs.com/en/4x/api.html#req.params)

#### Req.query:
This property looks very similar to *req.params* comparing the way both works, but the big difference is that it allows us to pass more parameters to the object.

```
...
routes() {
  this.app.get('/searchforusers', (req, res) => {
       const { index, name } = req.query;

       const getUser = users[index];

       return res.json(getUser.match(name))
   })
}
...
```
The first thing changed was the *path*, we are not passing any parameter anymore but it does not mean we can not use both properties together.
This property is passing the values through two parameters and we are using these parameters to find a specific string in the array.

*Open your browser and try to access the URL (http://localhost:3333/searchforusers?index=0&name=User01) to receive the string "User01". In this case, both parameters need to be true to return the desired value because we are trying to find the user based on the array index and if the name and string getUser is matching otherwise it will return null.*

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/jcarqeu04xirw2xuc3s2.JPG)

For more information, you can read the [documentation](http://expressjs.com/en/4x/api.html#req.query)

#### Post:

We will learn how to add a new string in our array using HTTP post requests.

Before we start, you should add the following lines in your routes.
```
...
routes() {
   this.app.post('/users', (req, res) => {
            const { user } = req.body;

            users.push(user)
             
            return res.json(users)
   })
}
...
```
*Open your insomnia to test the URL(http://localhost:3333/users) and then you need to add in the JSON body the following line ``{ "user": "User03" }``. In our HTTP request, we are sending through the req.body the string to add in our array.*

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/51hib7cqc81h86mij3mg.JPG)

The *path* is like the first *HTTP get request example* but we are using a different method.

For more information, you can read the [documentation](http://expressjs.com/en/5x/api.html#app.post.method)

#### Req.body:
This property is very useful because we can pass many parameters inside of the object in our *HTTP request*.

For more information, you can read the [documentation](http://expressjs.com/en/4x/api.html#req.body)

#### Put:

Update the strings inside of the array will be easy using the *HTTP put requests*.

Before we start, you should add the following lines in routes:
```
...
routes() {
   this.app.put('/users/:index', (req, res) => {
     const { index } = req.params;
     const { user } = req.body;

     users[index] = user;
             
     return res.json(users)
 })
}
...
```
*Open your insomnia to paste the URL(http://localhost:3333/users/0) and then you need to add in the JSON body the following line ``{ "user": "NewUser01" }``. We are sending the string through req.body to update our array based on the array index.*

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/b9wq150hq1lnfzuzo42i.JPG)

The *HTTP put request* is very useful when we want to update the specific string in our array, the parameter *index* is important to identify which index of the array will be updated with the string received through *req.body*.

For more information, you can read the [documentation](http://expressjs.com/en/5x/api.html#app.put.method)

#### Delete:

If we want to remove a string from our array we can use the *HTTP delete request*.

Before we start, you should add the following lines in your routes.

```
...
routes() {
   this.app.delete('/users/:index', (req, res) => {
      const { index } = req.params;

      users.splice(index, 1);
             
       return res.json(users)
  }) 
}
...
```
*Open your insomnia to paste the URL( http://localhost:3333/users/0) and to receive the array without the string "NewUser01". Basically the *req.params* receive the value through the *index parameter* to remove the string from the array based on the array index.*

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/u04z4uwtburj6daxewls.JPG)

The similarity with *HTTP put requests* is notable however it is important to determine which action we are using in our requests.

For more information, you can read the [documentation](http://expressjs.com/en/5x/api.html#app.delete.method)


### Conclusion:
In this tutorial, we learned how to create a new *node* project, setting up the express and the *nodemon* with *sucrase*, and how to use the *express* methods and properties.

And...

Doing an analogy between Dunder Mifflin Paper Company from The Office and the REST API. 
*HTTP get request* is the client asking for information about all the orders pending or just one specific order.
*HTTP post request* is the sales doing the enrolling of the new client.
*HTTP put request* is the client requesting for updating the quantity of the papers in the order.
*HTTP delete request* is the unsatisfied client requesting to cancel the order.


### Yes, we did it!
![Alt text of image] (https://media.giphy.com/media/ihBQKvIE7gLEA/giphy.gif)

#### We finished the tutorial, I hope I have contributed to your long trajectory of knowledge.

#### You can access the project [here](https://github.com/souzamarlon/nodejs-express-setup)

#### See you in the next tutorial!

![Alt text of image] (https://media.giphy.com/media/ui1hpJSyBDWlG/giphy.gif)