How to host a RESTful Node.js server with MongoDB Atlas database on Heroku
Tags: javascript, node, mongodb, beginners
Published: 2019-11-24 19:51:42

### Prerequisites 

* Node.js - Installed
* MongoDB Atlas  - AWS free tier cluster Account
* Text-editor - Visual Studio Code, Atom and etc.
* Git - Installed

*** *** ***

### Dependencies Used

 * cors       version 2.8.5
 * express    version 4.17.1
 * mongoose   version 5.7.12

---

### Assumptions 

The RESTful Node.js server with MongoDB database works when running on your localhost.

##### The MongoDB Connection String, you can find it by:
1. Sign-in at mongoDB Altas 
2. Locate the cluster you're using for server
3. Click " CONNECT" > Click " Connect Your Application

![alt text](https://i.postimg.cc/QdFnS3d1/mongodb.png)

##### Set MongoDB Altas - whitelist to **0.0.0.0/0** 

To set click 'Network Access' under Security tab > click 'ADD IP ADDRESS'

![alt text](https://i.postimg.cc/VNYhBGKM/Screenshot-from-2019-11-24-09-54-58.png"Whitelist")
###### note
**Whitelist** - MongoDB Atlas allows client connections to the cluster from entries in the project’s whitelist. You must add an entry to the whitelist to connect the client.CIDR notation 0.0.0.0/0 is used to allow all client connections to the cluster. However, you can add a specific IP address/es.

---

* Go to Heroku dashboard > Select your server App > Settings > Reveal Config Vars
 
![alt text](https://i.postimg.cc/rsmTsYLq/Screenshot-from-2019-11-24-08-06-33.png"Config Vars")

* Add ' MONGODB_URL ' as a Config Vars KEY in HEROKU, and add connection string as the VALUE then click 'Add'.


* Store  Cluster - connection string as a node.js process environment variable called ' MONGODB_URL ' in the main server javascript file.



##### For Example: server.js
```
const db = process.env.MONGODB_URL;

const connectDB = async () => {
  try {
    await mongoose.connect(db, {
      useUnifiedTopology: true,
      useNewUrlParser: true
    });
    console.log("MongoDB is Connected...");
  } catch (err) {
    console.error(err.message);
    process.exit(1);
  }
};
```

---

To allow inbound requests to the server using CORS

* Add FrontEnd site URL where it says "Your FrontEnd Website URL"

##### For Example:
```
// cors origin URL - Allow inbound traffic from origin
corsOptions = {
  origin: "Your FrontEnd Website URL",
  optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
};
app.use(cors(corsOptions));
```
---


###### note
The code example above is for allowing a single-origin if you want to allow more than one origin refer [here](https://www.npmjs.com/package/cors#installation) 

---

To Deploy select your App then click "Deploy" and choose one of the deployment methods.

![alt text](https://i.postimg.cc/1XFfGn1j/Screenshot-from-2019-11-24-12-32-15.png"Deployment")

---

Troubleshooting Tips

* If you encounter Heroku runtime errors you can view logs below

![alt text](https://i.postimg.cc/VsnThfg9/Screenshot-from-2019-11-24-12-13-07.png"View Logs")

###### note

* If you are getting errors stating Heroku can't find your modules when trying to deploy, it may be because you are using relative paths for example: `const connectDB = require("./config/db");`

You will have to use absolute paths because Heroku creates its own FileSystem at deployment.