Express/EJS/Mongooose Build from Zero to Deploy
April 19, 2022
Repo With Code From this tutorial for reference
This article assumes basic knowledge of ExpressJS, if your new to Express or Mongo I recommend starting with the following Video Playlists:
Mongo Setup
- go to mongodb.com and create an account
- create a new free cluster (all the defaults are fine)
- create username and password for accessing database (under database access)
- whitelist all IP addresses under network access (0.0.0.0)
- on the main dashboard, click on connect, select connecting your app and get the template url for connecting to your database.
mongo+srv://username:password@mongodb.com/databaseName
make sure the username and password sections have the username and password you created under database access and the databaseName part can be anything you like.
This is your Mongo URI.
Express Setup
Setup
- Open your IDE and terminal to an empty folder and type following commands
- create a server.js
touch server.js
- create a new npm project
npm init -y
- install dependencies
npm install express mongoose method-override ejs dotenv morgan
- install nodemon globally
npm install -g nodemon
- setup the following scripts in package.json
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js"
},
Summary of Dependencies
- express => web framework for create server and writing routes
- mongoose => ODM for connecting to and sending queries to a mongo database
- method-override => allows us to swap the method of a request based on a URL query
- ejs => our templating engine
- dotenv => will allow us to use a `.env` file to define environmental variables we can access via the `process.env` object
- morgan => logs details about requests to our server, mainly to help us debug
- create a
.env
file with the following dependencies
DATABASE_URL=<use your mongodb.com url>
PORT=4000
- create a
.gitignore
file with the following (always a good habit to make one even if you have a global .gitignore, the global is there to catch you in case)
/node_modules
.env
Setting Up Our server.js
Import our dependencies
/////////////////////////////////////////////
// Import Our Dependencies
/////////////////////////////////////////////
require("dotenv").config() // Load ENV Variables
const express = require("express") // import express
const morgan = require("morgan") //import morgan
const methodOverride = require("method-override")
const mongoose = require("mongoose")
Establish Database Connection
/////////////////////////////////////////////
// Database Connection
/////////////////////////////////////////////
// Setup inputs for our connect function
const DATABASE_URL = process.env.DATABASE_URL
const CONFIG = {
useNewUrlParser: true,
useUnifiedTopology: true
}
// Establish Connection
mongoose.connect(DATABASE_URL, CONFIG)
// Events for when connection opens/disconnects/errors
mongoose.connection
.on("open", () => console.log("Connected to Mongoose"))
.on("close", () => console.log("Disconnected from Mongoose"))
.on("error", (error) => console.log(error))
Create Our Todo Model
////////////////////////////////////////////////
// Our Models
////////////////////////////////////////////////
// pull schema and model from mongoose
const {Schema, model} = mongoose
// make fruits schema
const todoSchema = new Schema({
text: String
})
// make fruit model
const Todo = model("Todo", todoSchema)
Create App Object
/////////////////////////////////////////////////
// Create our Express Application Object
/////////////////////////////////////////////////
const app = express()
Register our Middleware
/////////////////////////////////////////////////////
// Middleware
/////////////////////////////////////////////////////
app.use(morgan("tiny")) //logging
app.use(methodOverride("_method")) // override for put and delete requests from forms
app.use(express.urlencoded({extended: true})) // parse urlencoded request bodies
app.use("/static", express.static("static")) // serve files from public statically
Our initial route
////////////////////////////////////////////
// Routes
////////////////////////////////////////////
app.get("/", (req, res) => {
res.render("index.ejs", {greeting: "Hello"})
})
Server Listener
//////////////////////////////////////////////
// Server Listener
//////////////////////////////////////////////
const PORT = process.env.PORT
app.listen(PORT, () => console.log(`Now Listening on port ${PORT}`))
The complete server.js file
/////////////////////////////////////////////
// Import Our Dependencies
/////////////////////////////////////////////
require("dotenv").config() // Load ENV Variables
const express = require("express") // import express
const morgan = require("morgan") //import morgan
const methodOverride = require("method-override")
const mongoose = require("mongoose")
/////////////////////////////////////////////
// Database Connection
/////////////////////////////////////////////
// Setup inputs for our connect function
const DATABASE_URL = process.env.DATABASE_URL
const CONFIG = {
useNewUrlParser: true,
useUnifiedTopology: true
}
// Establish Connection
mongoose.connect(DATABASE_URL, CONFIG)
// Events for when connection opens/disconnects/errors
mongoose.connection
.on("open", () => console.log("Connected to Mongoose"))
.on("close", () => console.log("Disconnected from Mongoose"))
.on("error", (error) => console.log(error))
////////////////////////////////////////////////
// Our Models
////////////////////////////////////////////////
// pull schema and model from mongoose
const {Schema, model} = mongoose
// make fruits schema
const todoSchema = new Schema({
text: String
})
// make fruit model
const Todo = model("Todo", todoSchema)
/////////////////////////////////////////////////
// Create our Express Application Object
/////////////////////////////////////////////////
const app = express()
/////////////////////////////////////////////////////
// Middleware
/////////////////////////////////////////////////////
app.use(morgan("tiny")) //logging
app.use(methodOverride("_method")) // override for put and delete requests from forms
app.use(express.urlencoded({extended: true})) // parse urlencoded request bodies
app.use("/static", express.static("static")) // serve files from public statically
////////////////////////////////////////////
// Routes
////////////////////////////////////////////
app.get("/", (req, res) => {
res.render("index.ejs", {greeting: "Hello"})
})
//////////////////////////////////////////////
// Server Listener
//////////////////////////////////////////////
const PORT = process.env.PORT
app.listen(PORT, () => console.log(`Now Listening on port ${PORT}`))
- create a views and static folder
mkdir views static
-
create index.ejs in the views folder with the following
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Our Basic Todo App</title> </head> <body> <%= greeting %>