Testing Out MongoDB + Express + React + Node + Sendgrid + Heroku
Tags: javascript, node, mongodb, react
Published: 2020-03-22 18:34:52

This post will capture how I got started building a simple web application to capture feedback about a piece of content - anything from an icon design to a business plan to a job posting. Here are the basic requirements: 
* create a feedback "record" (called a document in Couchbase, but it is just data in JSON form)
* upload a piece of content (that is actually a document, such as a PNG, PPT, DOC, etc.) by web or by email
* email all users specified in the feedback record with a copy of the document, asking them for feedback
* real-time chat between users that updates without a page refresh

# Build the basic data model

Although NoSQL databases like Couchbase allow you to worry less about the data model, starting with a clear definition of how you are thinking about your data is a smart first step. 

Check out this video for the difference between data modeling in RDBMS v. data modeling in Couchbase: [Data Modeling in Couchbase](https://youtu.be/Mj4PKKidREU)

Here is a first cut of the Couchbase data model for a document, which is the core object in the system - the thing that we want to get feedback on: 

```javascript
{
   "document":{
      "id":"integer",
      "title":"string",
      "type":"string",
      "createdDate":"datetime",
      "updatedDate":"datetime",
      "reviewers":[
         {
            "name":"string",
            "email":"string",
            "rating":"int"
         },
         {
            "name":"string",
            "email":"string",
            "rating":"int"
         }
      ],
      "comments":[
         {
            "name":"string",
            "email":"string",
            "body":"string"
         },
         {
            "name":"string",
            "email":"string",
            "body":"string"
         }
      ]
   }
}
```
##SQL v. NoSQL 
SQL: you need to invest heavily in your database design, because you immediately create a lot of scaffolding around the design - in the database, in the backend, and in the frontend. Simple changes to the data model require massive amounts of changes in your code base. 
NoSQL: you get to start with a simplified data model much quicker, and then you can evolve the data model over time. For example, instead of creating a user table, a comments table, and a documents table, and then associating the user table to the documents table through a many-to-many bridge table, etc., you can just start with the data structure above to get started. There are key scenarios that will need to be addressed down the road, such as what happens if a person updates their email address - how do you update all of the places where that email address exists. But why not solve those problems later, and focus on your most important problem up front: **can we find a pain worth solving that we can address with software we can build**. 

# Get Running on Heroku
This assumes that you have [Visual Studio Code](https://code.visualstudio.com/download) running on your machine. 

A great reference for getting started on Heroku is provided by Heroku itself: [Getting Started with NodeJS](https://devcenter.heroku.com/articles/getting-started-with-nodejs). It comes down to: 
* [Install Heroku Client](https://devcenter.heroku.com/articles/getting-started-with-nodejs#set-up) - this page also shows you how to check if you have Node, npm, and git installed. 
* Create your own Node Express app: this is NOT part of the Heroku tutorial, but instead of just copying their app we are going to write our own using another tutorial: [NodeJS API Tutorial](https://youtu.be/CsWoMpK3EtE?t=76) - just watch to minute 4 (unless you want to learn about Docker). key steps: 
  * create a folder called...heroku
  * open the folder in Code
  * create a file in Code called app.js
  * paste in this code
```javascript
const express = require('express')
const app = express()

app.get('/', (req, res) => res.send('I am alive!')); 

app.listen(3000, () => {
    console.log('I am alive on port 3000!'); 
});  
```
* Create your own Node app (cont)
  * in code, hit Terminal > New Terminal 
  * in the Terminal, type 

```
npm init
```
* Create your own Node app (cont)
  * accept all the defaults
  * Open the pakcage.json file that was created with the last command
  * back in Terminal, type
```
npm install --save express
npm install --save nodemon
```
* Create your own Node app (cont)
  * you should see express appear as a dependency in package.json. 
  * in the package.json file, inside the scripts element, add a start instruction
```javascript
"scripts": {
    "start": "nodemon app.js", 
    "test":...
}
```
* Create your own Node app (cont)
  * to start the application, in the terminal type
```
npm run start
```
* Create your own Node app (cont)
  * head on over to [localhost:3000](http://localhost:3000) and you should see your shiny new app. Whenever a change is made, nodemon will pick it up and republish your app. Try it. 
  * when you are done testing your app, type CTRL+C in the Terminal to terminate the job. 
* Now that you have created your node app, you can configure the app for Git. 
```
git init
```
* and then you can publish it via the Terminal with 
```
heroku create
```
* This will create a home for your application on Heroku and create the git connection between your machine and the Heroku git repository.  
* Now you are ready for my favorite haiku: 
```
git add .
git commit -m "my first commit"
git push heroku master
```
* There should be a funny name for your application, such as https://shrouded-atoll-61606.herokuapp.com/

# Get Mongo running
First, [install Mongo on your local machine](https://www.mongodb.com/dr/fastdl.mongodb.org/win32/mongodb-win32-x86_64-2012plus-4.2.3-signed.msi/download). Then get the node mongo driver:
```
npm install --save mongodb
```

Add this to your app.js file
```javascript
const MongoClient = require('mongodb').MongoClient;
const uri = "mongodb+srv://<username>:<password>@<your-cluster-url>/test?retryWrites=true&w=majority";
const client = new MongoClient(uri, { useNewUrlParser: true });
client.connect(err => {
  const collection = client.db("test").collection("devices");
  // perform actions on the collection object
  client.close();
});
```
Now that you have everything working locally, you need to configure it for Heroku. mLab has a free sandbox option for running MongoDB, so we will use that. Go to your Heroku dashboard, find your application, click "Configure Add Ons" and search for mLab MongoDB. Add the free version. 


More to come soon!