DEV Community

Karina
Karina

Posted on • Updated on

Setting up a server with Node.js, Express, MongoDB, etc. 😼

a cute kitteh

Intro

These are the notes I took as I learned how to set up a server and API on my computer with Node.js, Express, MongoDB, and other dependencies.

This is the order I like to set things up every time I start a new project. Depending on what I'm making I don't install some dependencies shown here or I'll install others.

I took these notes while watching Mayanwolfe's twitch streams and making my projects so a special thanks and shoutout to her.


"We don't get got, we go get!" -#100Devs war cry

I got got many times while learning how to set up my servers and APIs. I'm hoping that with these notes I won't get got again and I prevent someone else from getting got too.


You'll need to have Node.js installed and accounts in MongoDB and Heroku, plus the Heroku CLI downloaded.

The main parts of your setup will be:

  1. initialize npm and install dependencies
  2. require what you need and listen
  3. set up your .env and .gitignore files
  4. declare your MongoDB variables
  5. connect to MongoDB
  6. set up your middleware
  7. create your public and views folders and relevant files
  8. set up your GET (and POST, PUT, DELETE)
  9. push your server to Heroku
  10. bask in the glory of having built your own server

Let's go!


Initialize npm and Install Dependencies

Create your project folder and your server.js file inside that folder. I use the bash terminal in VSCode and the mkdir and touch commands.

In the terminal, initialize npm:

npm init -y
Enter fullscreen mode Exit fullscreen mode

The -y flag makes it so that you don't have to press enter a bunch of times.

Next, install the dependencies that you'll use in your projects. Lately, I tend to use express, dotenv, cors if I'm setting up a local API, MongoDB, ejs sometimes, and nodemon.

In the terminal again, write

npm i express dotenv cors mongodb ejs
Enter fullscreen mode Exit fullscreen mode

The i stands for install, you can install your dependencies one by one (writing npm i each time), or all at once as above.
Nodemon is different. For nodemon, write

npm i nodemon --save-dev
Enter fullscreen mode Exit fullscreen mode

as it's a tool to be used only while developing. You can go to your package.json file to check that everything is installed correctly.
While there, go to "scripts" and after "start": ... add

"start": "node server.js",
"dev": "nodemon server.js"
Enter fullscreen mode Exit fullscreen mode

don't forget the comma.
Now in the terminal you can write

npm run dev
Enter fullscreen mode Exit fullscreen mode

and have the server restart on its own any time you make changes and save.

Require and Listen

Just downloading isn't enough. You need to require the dependencies to be able to use them.

Back in your server.js file, write

const express = require('express')
const app = express()
const cors = require('cors')
const MongoClient = require('mongodb').MongoClient
require('dotenv').config()
const PORT = 8000
Enter fullscreen mode Exit fullscreen mode

app.listen() goes at the very end of your code, but you can set it up now to test that your server is working. In your server.js write

app.listen(PORT, () => {
  console.log(`Go catch the server at PORT ${PORT}`)
})
Enter fullscreen mode Exit fullscreen mode

Save your code. Open your browser and write localhost:8000, or whatever number you put in your PORT variable, in the URL bar. Your console.log message should appear in your terminal, and since your server is not set up to respond with anything you'll see

Cannot GET /

in your browser, which is totally fine right now.

Set up your .env and .gitignore files

If you were running nodemon, click in your terminal and hit Ctrl + C to get your repl back and be able to type again.

Before pushing your project up to github you should create a .gitignore file so that your gigantic list of node_modules won't be pushed as well. .env is for sensitive information, like your mongodb password so that needs to go in your .gitignore file too.
In your terminal write

touch .gitignore .env
Enter fullscreen mode Exit fullscreen mode

Open .gitignore and write

node_modules
.env
Enter fullscreen mode Exit fullscreen mode

Save, then delete your PORT variable from server.js and write PORT = 8000 in your .env file (don't write const or let).

Go back to your app.listen in server.js and change it to

app.listen(process.env.PORT || PORT, () => {
  console.log(`Go catch the server at PORT ${process.env.PORT || PORT}`);
})
Enter fullscreen mode Exit fullscreen mode

Save all your files.

Now you're ready to create a repository and start pushing.

In your terminal write

git init
Enter fullscreen mode Exit fullscreen mode

and then

git add .
Enter fullscreen mode Exit fullscreen mode

then go to your GitHub and create a new repository. On the set up page, copy the section from git commit .... to git push and paste that into your terminal, hitting enter until done.

Declare your MongoDB variables

Assuming you're connecting to a MongoDB database for your project, in your server.js, between your requires and app.listen, write

let db,
  dbConnectionString = process.env.DB_STRING,
  dbName = '',
  collection
Enter fullscreen mode Exit fullscreen mode

process.env.DB_STRING means that server.js is getting DB_STRING from your .env file.

Go to your MongoDB Database Deployments page, click Connect, then click Connect your application. Copy the connection string then go to your .env file and write

DB_STRING = 
Enter fullscreen mode Exit fullscreen mode

pasting the connection string in the DB_STRING variable. The string will have <password> in it. Replace that bit, including the <>, with your password.

If you forgot your password or need to change it because you messed up the steps with git, .gitignore and .env files, exposing your password on GitHub, like I did several times, click on MongoDB's Database Access under Security on the left and click Edit. Make sure you scroll down and hit Update User after changing your password. It takes a minute to deploy.

dbName is your database's name. Get it at MongoDB's Database Deployments page and click Browse Collections. There's a list of your databases on the left side. Write the name of the database you want to access in the dbName variable as a string.
Add, commit, and push to git.

Connect to MongoDB

Back in server.js, write

MongoClient.connect(dbConnectionString)
  .then(client => {
    console.log(`Connected to the ${dbName} database`)
    db = client.db(dbName)
    collection = db.collection('')
})
Enter fullscreen mode Exit fullscreen mode

under your MongoDB variables. In MongoDB, click on your database name to see the collections in it. Write the collection's name in between the single quotes in db.collection.
Save everything then write npm run dev or npm start in the terminal to start your server and see if you connected. Your console will log your messages.
Keep adding, committing, and pushing to git.

Set up your Middleware

After your MongoClient.connect, set up your middleware.

app.set('view engine', 'ejs')
app.use(express.static('public'))
app.use(express.urlencoded({extended: true}))
app.use(express.json())
app.use(cors())
Enter fullscreen mode Exit fullscreen mode

Now your code knows to render ejs, access public files, handle urls, and parse api data.
Git add, commit, push.

Create your public and views folders and files

In your terminal write

mkdir public views
Enter fullscreen mode Exit fullscreen mode

In your public folder make a js file and a css file, in your views folder make an index.ejs file. A quick way to do it using the terminal is writing

touch public/main.js public/style.css views/index.ejs
Enter fullscreen mode Exit fullscreen mode

in it. Fill in your content and remember to link css and js files in your ejs file, but you don't need to include public/ before the file names.

Set up your GET

You can set up a simple get to check that everything is working correctly.
Back in server.js after the middleware, write

app.get('/', (req, res) => {
  res.render('index.ejs')
})
Enter fullscreen mode Exit fullscreen mode

Save your code, run your server and refresh your browser to check that your ejs file is rendering.
You can also put your collection into an array and render it in a console.log to check what's coming back from your database, but be careful with this if you have a lot of data. Refresh your browser to see the results.

app.get('/', (req, res) => {
  collection.find().toArray()
  .then (results => {
    res.render('index.ejs')
    console.log(results)
  })
})
Enter fullscreen mode Exit fullscreen mode

Now you can either finish out your CRUD methods or

Push your server to Heroku

Heroku needs to be able to access your DB_STRING. but it uses git commands so you need to delete .env from the .gitignore file when you push to Heroku.
Do one last save, add ., commit and push to GitHub, then delete .env from .gitignore. Go to server.js and in the terminal write

heroku login
Enter fullscreen mode Exit fullscreen mode

It'll open a window in your browser to login then you can close it when you're done. Back in the terminal, if you want Heroku to create a name for you, write

heroku create
Enter fullscreen mode Exit fullscreen mode

If you have a name in mind write it after create but before hitting enter.

Next, in the terminal, write

echo "web: node server.js" > Procfile
Enter fullscreen mode Exit fullscreen mode

which will create a Procfile folder.

Now do a regular git add . and git commit -m'comment' but when pushing, write

git push heroku main
Enter fullscreen mode Exit fullscreen mode

It's deployed! Now go to your dashboard in Heroku, click on your project's name, go to settings, click on Reveal Config Vars, write your db string variable name in the 'key' box and the string in the value box, and click Add. This will make it so Heroku can access your DB_STRING to connect to MongoDB. Make sure you write .env again in .gitignore now, don't leave it for later. Whenever you push to git write .env, to push to Heroku delete .env.
Another problem I faced at this step was Heroku not being able to access my database unless I whitelisted all IP addresses at MongoDB. I think this is ok for my small projects but I'm looking for a solution to use when I start making bigger projects.

Next, I want to review my CRUD methods and other tools like Mongoose.

Top comments (0)