Build a REST API with Node.js: Deploying to Heroku (Finale)
Tags: node, restapi, heroku, javascript
Published: 2020-12-29 06:12:27

---
title: Build a REST API with Node.js: Deploying to Heroku (Finale)
published: true
date: 2020-08-08 02:49:39 UTC
tags: Nodejs,RESTAPI,Heroku,JavaScript
canonical_url: https://lo-victoria.com/build-rest-api-with-nodejs-deploy-to-heroku
---

Hello everyone! Welcome back to [Let's Build a Node.js REST API Series](https://hashnode.com/series/lets-build-a-nodejs-rest-api-ckcov1aob00dcfms19o5g2x42) - the finale. We are finally finishing this API. It's been a long series and we're finally here!

If you are new to this series, please check out the previous articles to follow along:
1. [Designing and Planning the API](https://lo-victoria.com/build-a-nodejs-api-for-beginners-1-designing-and-planning-your-api-ckdcat2o903cj66s1g7tu0cds)
2. [Routes and Controllers](https://lo-victoria.com/build-a-nodejs-api-for-beginners-2-routes-and-controllers-ckder50v20005xxs13rfsg1r8)
3. [Integrating MongoDB Atlas](https://lo-victoria.com/build-a-nodejs-api-for-beginners-3-integrating-mongodb-atlas-ckdgk9irb00ikdns16xr5b5et)
4. [Finalizing Controllers](https://lo-victoria.com/build-a-nodejs-api-for-beginners-4-finalizing-controllers-ckdi6itoe0097wgs1hr4530c6)
5. [Upload an Image File](https://lo-victoria.com/build-a-nodejs-api-for-beginners-5-upload-an-image-file-ckdjl0cbq01vpz2s15dk37yqj)

Today, we are going to prepare the API for deployment! To do that, first we need to add some security and compression.

## Step 1: Security
We are using helmet to take care of our app security. Read the [Must-Have Security Checklist](https://lo-victoria.com/the-must-have-security-checklist-for-web-apps-ckbylrdbq0090aws10ntp5vho) for more details on helmet. 

To install it, run:
```
npm install --save helmet
```
Then include the following in **server.js**:
``` 
// add this line below the other import statements
const helmet = require('helmet');

// add this line below const app = express();
app.use(helmet());

```
Another security feature we can add is route protection. This is because we don't want every user to have access to create new tea or to delete all tea in our API. That would be tragic! 

For this API, I have implemented basic API header authorization to restrict access to certain routes but that is out of the scope of this series, as I want it to be as beginner-friendly as possible. A separate article on API authentication methods coming soon.

## Step 2: Compression
We can compress HTTP requests to significantly reduce the time required for the client to get and load the page from the server. To do that, we can use compression.

Install it with:
```
npm install compression
```
Then add the following before the routes in server.js:
```
// add this line below the helmet import statement
const compression = require('compression');

// add this below app.use(helmet())
app.use(compression()); //Compress all routes
```

## Step 3: Preparation for heroku
For this API, I'm deploying it to [heroku](https://www.heroku.com/). It is a cloud-based platform to build, deliver and monitor web apps such as this API. But there are plenty of options like:
- AWS
- DigitalOcean
- Google Cloud
- Firebase
- Microsoft Azure
- Many more...

### 1. Github
First, ensure you have your API in a Github repo. This is because heroku is integrated with git so it makes it easier for future changes.

### 2. package.json
Check your node version by running:
```
node --version
```
The console will output your Node version. Copy it, and include it in the "engines" key to add to your package.json:
```
  "engines": {
    "node": "12.14.1"
  },
```

And make sure your package.json has the following configuration for the "main" and "scripts" keys.
```
"main": "server.js",
"scripts": {
    "start": "node server.js",
    "test": "echo \"Error: no test specified\" && exit 1"  //optional
  },
```
### 3. Procfile and index.html
Create a file name 'Procfile' in the root directory and add
```
web:node server.js
```
This is to instruct heroku to run the command 'node server.js' as soon as it starts the app.

Optionally, create a `index.html` so the API would at least have a face when it first loads. I'm making a simple one with a heading and paragraph element.
```
<h1>Welcome to T-API</h1>
<p>The Tea API for all Tea Lovers~</p>
```
Remember to add its route in server.js so that index.html will be static, which allows the API to access it when the server starts.
```
// add this below app.use("/", routes) to make index.html a static file
app.route('/')
  .get(function (req, res) {
    res.sendFile(process.cwd() + '/index.html');
});
```

### 4. MongoDB
We are almost there! Finally, we add 2 more options into our `mongoose.connect()` method in our server.js file:
```
server: { 
   socketOptions: { keepAlive: 300000, connectTimeoutMS: 30000 } 
}, 
replset: {
   socketOptions: { keepAlive: 300000, connectTimeoutMS : 30000 } 
} 
```
This prevents heroku from returning a timeout error 503, just in case. Here's the final version of the `mongoose.connect()` method in our server.js file:
```
mongoose.connect(
  process.env.MONGODB_URI,
  {
    useFindAndModify: false,
    useUnifiedTopology: true,
    useNewUrlParser: true,
    useCreateIndex: true,
    server: { socketOptions: { keepAlive: 300000, connectTimeoutMS: 30000 } },
    replset: { socketOptions: { keepAlive: 300000, connectTimeoutMS: 30000 } },
  },
  function (err) {
    if (err) return console.log("Error: ", err);
    console.log(
      "MongoDB Connection -- Ready state is:",
      mongoose.connection.readyState
    );
  }
);
```
Great! We have prepared what we need to deploy our app to heroku.

## Step 4: Heroku
Create an account for free at www.heroku.com.

Then download the heroku CLI [here](https://devcenter.heroku.com/articles/heroku-cli) and follow their instructions on that page to install it.

Once you have installed the CLI, you can now use heroku commands on your command prompt to deploy the API. Head to the project's root directory and run:
```
heroku create <app-name>
```
Then, let's make the final push:
```
git push heroku
```
Great! We have deployed the API! But because environment variables don't get deployed, we need to configure our `process.env.MONGODB_URI` first before starting the app. 

Configure by running the command in your command prompt:
```
heroku config:set MONGODB_URI="<your url here>"
```
### All done!
Finally, run the following to make sure an instance of the app always runs:
```
heroku ps:scale web=1
```
Let's visit the site with:
```
heroku open
```
The `index.html` will load as the entry page like shown below. It's just an empty white page with words for now. Make sure to make the file static so that it is accessible by the server to render. In **server.js**:
```
//Index page at default entry route
app.route("/").get(function (req, res) {
  res.sendFile(process.cwd() + "/index.html");
});
```

![page.PNG](https://cdn.hashnode.com/res/hashnode/image/upload/v1596497780744/GJF2SjDcd.png)

Right now, we don't have a user-friendly interface to test our API on the browser. But we can simply add our routes in the URL manually. As seen in the image above, my API is deployed at `https://tea-api-vic-lo.herokuapp.com/`. If I enter `https://tea-api-vic-lo.herokuapp.com/tea`, it should GET our '/tea' route and returned all our tea objects like so:

![ugly.PNG](https://cdn.hashnode.com/res/hashnode/image/upload/v1596497767174/6O8oTBQ4W.png)

Of course, I went ahead to populate (POST) some tea objects first or the URL will return an empty object. As seen in the image above, the URL returns the tea object I created earlier correctly and therefore, the API works! Yay!

## Congratulations!
We have finally finished building a working REST API with Node.js, MongoDB and Express! I hope this series has been very helpful for you in understanding routes, controllers, databases and how APIs work. If you visit the site where my T-API is deployed, you can see that I have made a fully responsive user interface for the API. I'll write and publish an article on how to create a front-end of an API soon so stay tuned.

Thank you for reading and following this series. I am very grateful to have received your generous words and feedback. We shall end off this series on a good note. Any comments or questions, as usual, please feel free to share them below. I hope you love tea and APIs now. Cheers!

👉 Here is where you can find my T-API: https://tea-api-vic-lo.herokuapp.com/

👉 Refer to the Github repo if you need to see the source code: https://github.com/victoria-lo/TAPI


### Further Reading
- [About compression](https://www.npmjs.com/package/compression)
- [About helmet](https://www.npmjs.com/package/helmet)
- [Must-Have Security Checklist](https://lo-victoria.com/the-must-have-security-checklist-for-web-apps-ckbylrdbq0090aws10ntp5vho)
- [Some hosting platform for web apps](https://geekflare.com/nodejs-hosting-platform/)
- [Get started with heroku for Node.js](https://devcenter.heroku.com/articles/getting-started-with-nodejs)
- [Deploying Node.js Apps to heroku](https://devcenter.heroku.com/articles/deploying-nodejs)