Setting Up a Simple, Secure and Robust Node JS Server
Tags: node, express, javascript, api
Published: 2020-02-03 14:38:36

In this tutorial, we will be setting up a simple server - first, without ``express`` and then with ``express``.

I assume that you already understand the theory behind ``Node.js``, ``express`` and ``nodemon`` so we will just go straight to practicals.

## Table Of Contents
* [Install Node.js and NPM](#1)
* [Check if installation was successful](#2)
* [Create a Node server without Express](#3)
* [Test our server](#4)
* [Send Back a Response From our Server](#5)
* [Create a Node Server With Express](#6)
* [Secure your server. Make it Future-proof](#7)
* [Conclusion](#8)

<a name="1"></a>
## Install Node.js and NPM *(if you have not done so)*

1. Go to [node.js website](https://nodejs.org/en/)
2. Click on the recommended download button 

![nodejs page](https://dev-to-uploads.s3.amazonaws.com/i/w8serczfcoq9acndquk9.JPG)

When the download is complete, install node.js using the downloaded ``.exe`` file *(It follows normal installation process)*.

<a name="2"></a>
### Check if installation was successful 

1. Go to your terminal/command prompt *(run as administrator if possible)*
2. Type in each of the following and hit Enter button

<pre>
    node -v

    npm -v
</pre>

Your output should be similar to the image below.

![Testing node and npm version](https://dev-to-uploads.s3.amazonaws.com/i/wgfll8lga8s9kr207u6r.JPG)

The version maybe different but that is OK.

<a name="3"></a>
## Create a Node server without Express 
For the rest of this tutorial, I will be using VS code editor. You can use whatever editor you choose.

1. Let's start by creating a project directory. Start a terminal and type the following to create a directory and open it.

<pre>
  mkdir server-tutorial
  cd server-tutorial
</pre>

I named my project directory: ``server-tutorial`` *(you can name yours as you please)*.

2. In the terminal, type in the following: ``npm init``. Hit the ``Enter`` button for all prompts. When completed, you should have a ``package.json`` file seated in your project directory.

The ``package.json`` file is just a file with all the details of your project. You don't have to open it.

* Create a file ``index.js`` 

* In the file, require the ``HTTP`` module like so:

  ```javascript
    const http = require('http');
  ```

* Call the ``createServer()`` method on it and assign it to a constant like so

  ```javascript
    const server = http.createServer();
  ```

* Call the ``listen()`` method on the server constant like so 

  ```javascript
    server.listen();
  ```

* Give it a port to listen to. Now this could be any free port but we will be using port ``3000`` which is the conventional port. So we have 

  ```javascript
    const http = require('http');

    const server = http.createServer();

    server.listen(3000);
  ```

Basically, that is all you need do to create a server. 

 <a name="4"></a>
### Test our server.
1. In your terminal *(should be in the project directory)*, type ``node index.js`` and hit the ``Enter`` button.

2. Open a new tab in [``postman``](https://www.getpostman.com/) or any web ``browser`` and in the address bar, type ``http://localhost:3000/`` and hit the ``Enter`` button. **(I will be using postman because of it extended functionalities outside the box)**

You will notice that your browser or postman keep loading indefinitely like so

![Postman Loading Indefinitely](https://dev-to-uploads.s3.amazonaws.com/i/fp7k6pcfctn0548n0rmx.JPG)

Yaye... That is fine. Our Server is up and running.

But it's boring already. We need to make the server talk to us.

**Let's get to it immediately**.

<a name="5"></a>
### Send Back a Response From our Server 
Back in our code, add the following to ``const server = http.createServer();``

  ```javascript
   (request, response) => {
      response.end('Hey! This is your server response!');
   }
  ```

So we now have:

```javascript
  const http = require('http');

  const server = http.createServer((request, response) => {
    response.end('Hey! This is your server response!');
  });

server.listen(3000);
```

In a layman's term, the ``request`` object tells the ``server`` that we want something, the ``response`` object tells us what the ``server`` has to say about our ``request`` and the ``end()`` method terminates the communication with the ``server`` ``response``. 

**Hopefully, that makes sense!**

Now, test the server again following the steps we outlined above and your server should be talking to you. This is my output:

![Postman returning a response](https://dev-to-uploads.s3.amazonaws.com/i/b0189qzrdkppbvr57uo8.JPG)

Feel free to change the string as you wish. 

Use ``Control/Command + C`` to terminate the server and run ``node index`` to start the server again.

**Looking Sharp! Right? All good...**

<a name="6"></a>
## Create a Node Server With Express 
In this section, we want to make our lives easier using ``Express`` and ``Nodemon`` (node-mon or no-demon, pronounce as you wish).

* In the terminal, install the following

<pre>
  npm install express --save
  npm install nodemon --save-dev
</pre>

* Create a new file name it ``app.js`` or whatever suits you

* In the file, 

i. Require express like so

``const express = require('express');``

ii. Assign the express method to a constant like so

``const app = express();``

iii. Export the app constant to make it available for use in other files within the directory like so

``module.exports = app;``

So we have:

```javascript
const express = require('express');

const app = express();



module.exports = app;
```

* In the ``index.js`` file, require the ``app`` we exported a while ago like so

``const app = require('./app');``

* Set the port using the app like so

``app.set('port', 3000);``

* Replace the code in the ``http.createServer()`` method with just ``app`` like so

``const server = http.createServer(app);``

This directs all API management to the ``app.js`` file helping with separation of concerns.

So our ``index.js`` file now looks like this

```javascript
const http = require('http');
const app = require('./app');

app.set('port', 3000);
const server = http.createServer(app);

server.listen(3000);
```

* Back in our ``app.js`` file, since we have directed all API management to here, let's create an API to speak to us like before.

So before the ``module.exports = app``, add the following

```javascript
app.use((request, response) => {
   response.json({ message: 'Hey! This is your server response!' }); 
});
```

We now have:

```javascript
const express = require('express');

const app = express();

app.use((request, response) => {
   response.json({ message: 'Hey! This is your server response!' }); 
});

module.exports = app;
```

Ahaaa... It's time to test our app

To test our app, we now type ``nodemon index`` in our terminal and hit the ``Enter`` button. This is my terminal

![Terminal running nodemon](https://dev-to-uploads.s3.amazonaws.com/i/1gy6psmeylb6onbbt18i.JPG)

**Do you notice that nodemon gives us details of execution in the terminal unlike node? That's the beauty of nodemon.**

You can now go to ``postman`` or any ``browser`` and in the address bar, type ``http://localhost:3000/`` and hit ``Enter`` button. See my output:

![Postman returning response from express app](https://dev-to-uploads.s3.amazonaws.com/i/m4yrqaf3d235xo7hjqae.JPG)

**Walah!!! It's working.**

Now more reason to use nodemon. Go to the ``app.js`` file and change the ``message`` string to any string on your choice, save and watch the ``terminal``.

![nodemon restarting after changes](https://dev-to-uploads.s3.amazonaws.com/i/qcslu7vqa746nq5hvjwk.JPG)

**Wow... It automatically restarts the server. This was impossible with node. We had to restart the server ourselves.**

<a name="7"></a>
## Secure your server. Make it Future-proof 
1. In the ``index.js`` file, replace all the code with the following:

```javascript
const http = require('http');
const app = require('./app');

const normalizePort = val => {
  const port = parseInt(val, 10);

  if (isNaN(port)) {
    return val;
  }
  if (port >= 0) {
    return port;
  }
  return false;
};
const port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

const errorHandler = error => {
  if (error.syscall !== 'listen') {
    throw error;
  }
  const address = server.address();
  const bind = typeof address === 'string' ? 'pipe ' + address : 'port: ' + port;
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges.');
      process.exit(1);
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use.');
      process.exit(1);
      break;
    default:
      throw error;
  }
};

const server = http.createServer(app);

server.on('error', errorHandler);
server.on('listening', () => {
  const address = server.address();
  const bind = typeof address === 'string' ? 'pipe ' + address : 'port ' + port;
  console.log('Listening on ' + bind);
});

server.listen(port);
```

``process.env.PORT`` makes the app dynamic so that it can run any port assigned to it in the future when hosted on a live server

The  ``normalizePort``  function returns a valid port, whether it is provided as a number or a string

The ``errorHandler`` function checks for various errors and handles them appropriately — it is then registered to the server

A ``listening`` event listener is also registered, logging the port or named pipe on which the server is running to the console

**YooH! Our server is more secure and robust right now. Notice that nodemon also displays the port we are listening on now.**

There you have it, a simple, secure and robust nodejs server

<a name="8"></a>
## Conclusion 
We have been able to learn how to create a server using just nodejs after which, we improved our server using express and nodemon.

All codes can be found [here](https://github.com/EBEREGIT/server-tutorial/tree/create-server)

{% github eberegit/server-tutorial no-readme %}

Up next, we will be looking at [Image Upload to cloudinary using nodejs and express](https://dev.to/ebereplenty/image-upload-to-cloudinary-with-nodejs-and-dotenv-4fen).

If you have questions, comments or suggestions, please drop them in the comment section.

You can also follow me and message me on social media platforms. 

**[Twitter](https://twitter.com/eberetwit) | [LinkedIn](https://www.linkedin.com/in/samson-ebere-njoku-profile/) | [Github](https://github.com/EBEREGIT)**

Thank You For Your Time.