MERN Stack Build Part 1
In this build we will:
- Build an Express API
- Use Mongo/Mongoose with 1 model
- Deploy the API with Heroku
- Build a Full CRUD Frontend with React
- Deploy with Netlify
Setup for Express Build
- Create a folder called
express-react
- Inside this folder create another folder called
backend
- Generate a React app called frontend
npx create-react-app frontend
Your folder structure should look like this...
/express-react
-> /backend
-> /frontend
cd
into thebackend
folder
Setting up the Express app
Make files touch .env .gitignore server.js
- Create a new node project
npm init -y
- Install dependencies
npm install dotenv mongoose express cors morgan
- Install dev dependencies
npm install --save-dev nodemon
- Setup
npm
scripts
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js"
}
- Put the following
.gitignore
/node_modules
.env
- Put the following in
.env
(make sure to use YOUR mongodb.com uri)
MONGODB_URL=mongodb+src://...
PORT=4000
Starting Server.js
Let's build out the minimum to get server.js
running:
///////////////////////////////
// DEPENDENCIES
////////////////////////////////
// get .env variables
require("dotenv").config();
// pull PORT from .env, give default value of 4000
const { PORT = 4000 } = process.env;
// import express
const express = require("express");
// create application object
const app = express();
///////////////////////////////
// ROUTES
////////////////////////////////
// create a test route
app.get("/", (req, res) => {
res.send("hello world");
});
///////////////////////////////
// LISTENER
////////////////////////////////
app.listen(PORT, () => console.log(`listening on PORT ${PORT}`));
Run the server npm run dev
and make sure you see "Hello World"
when you go to localhost:4000
.
Adding a Database Connection
Let's update our server.js
to include a database connection:
///////////////////////////////
// DEPENDENCIES
////////////////////////////////
// get .env variables
require("dotenv").config();
// pull PORT from .env, give default value of 4000
// pull MONGODB_URL from .env
const { PORT = 4000, MONGODB_URL } = process.env;
// import express
const express = require("express");
// create application object
const app = express();
// import mongoose
const mongoose = require("mongoose");
///////////////////////////////
// DATABASE CONNECTION
////////////////////////////////
// Establish Connection
mongoose.connect(MONGODB_URL, {
useUnifiedTopology: true,
useNewUrlParser: true,
});
// Connection Events
mongoose.connection
.on("open", () => console.log("You are connected to mongoose"))
.on("close", () => console.log("You are disconnected from mongoose"))
.on("error", (error) => console.log(error));
///////////////////////////////
// ROUTES
////////////////////////////////
// create a test route
app.get("/", (req, res) => {
res.send("hello world");
});
///////////////////////////////
// LISTENER
////////////////////////////////
app.listen(PORT, () => console.log(`listening on PORT ${PORT}`));
Make sure you see the Mongoose Connection message when the server restarts
Adding the People Model
- Let's add a People model to
server.js
along with an index and create route to see and create our people. - Make sure to add
cors
andexpress.json
middleware!
///////////////////////////////
// DEPENDENCIES
////////////////////////////////
// get .env variables
require("dotenv").config();
// pull PORT from .env, give default value of 4000
// pull MONGODB_URL from .env
const { PORT = 4000, MONGODB_URL } = process.env;
// import express
const express = require("express");
// create application object
const app = express();
// import mongoose
const mongoose = require("mongoose");
// import middlware
const cors = require("cors");
const morgan = require("morgan");
///////////////////////////////
// DATABASE CONNECTION
////////////////////////////////
// Establish Connection
mongoose.connect(MONGODB_URL, {
useUnifiedTopology: true,
useNewUrlParser: true,
});
// Connection Events
mongoose.connection
.on("open", () => console.log("You are connected to mongoose"))
.on("close", () => console.log("You are disconnected from mongoose"))
.on("error", (error) => console.log(error));
///////////////////////////////
// MODELS
////////////////////////////////
const PeopleSchema = new mongoose.Schema({
name: String,
image: String,
title: String,
});
const People = mongoose.model("People", PeopleSchema);
///////////////////////////////
// MiddleWare
////////////////////////////////
app.use(cors()); // to prevent cors errors, open access to all origins
app.use(morgan("dev")); // logging
app.use(express.json()); // parse json bodies
///////////////////////////////
// ROUTES
////////////////////////////////
// create a test route
app.get("/", (req, res) => {
res.send("hello world");
});
// PEOPLE INDEX ROUTE
app.get("/people", async (req, res) => {
try {
// send all people
res.json(await People.find({}));
} catch (error) {
//send error
res.status(400).json(error);
}
});
// PEOPLE CREATE ROUTE
app.post("/people", async (req, res) => {
try {
// send all people
res.json(await People.create(req.body));
} catch (error) {
//send error
res.status(400).json(error);
}
});
///////////////////////////////
// LISTENER
////////////////////////////////
app.listen(PORT, () => console.log(`listening on PORT ${PORT}`));
- Create 3 people using postman to make post requests to
/people
- Test the index route with a get request to
/people
Update and Delete
Let's add an Update and Delete API Route to server.js
:
///////////////////////////////
// DEPENDENCIES
////////////////////////////////
// get .env variables
require("dotenv").config();
// pull PORT from .env, give default value of 4000
// pull MONGODB_URL from .env
const { PORT = 4000, MONGODB_URL } = process.env;
// import express
const express = require("express");
// create application object
const app = express();
// import mongoose
const mongoose = require("mongoose");
// import middlware
const cors = require("cors");
const morgan = require("morgan");
///////////////////////////////
// DATABASE CONNECTION
////////////////////////////////
// Establish Connection
mongoose.connect(MONGODB_URL, {
useUnifiedTopology: true,
useNewUrlParser: true,
});
// Connection Events
mongoose.connection
.on("open", () => console.log("You are connected to mongoose"))
.on("close", () => console.log("You are disconnected from mongoose"))
.on("error", (error) => console.log(error));
///////////////////////////////
// MODELS
////////////////////////////////
const PeopleSchema = new mongoose.Schema({
name: String,
image: String,
title: String,
});
const People = mongoose.model("People", PeopleSchema);
///////////////////////////////
// MiddleWare
////////////////////////////////
app.use(cors()); // to prevent cors errors, open access to all origins
app.use(morgan("dev")); // logging
app.use(express.json()); // parse json bodies
///////////////////////////////
// ROUTES
////////////////////////////////
// create a test route
app.get("/", (req, res) => {
res.send("hello world");
});
// PEOPLE INDEX ROUTE
app.get("/people", async (req, res) => {
try {
// send all people
res.json(await People.find({}));
} catch (error) {
//send error
res.status(400).json(error);
}
});
// PEOPLE CREATE ROUTE
app.post("/people", async (req, res) => {
try {
// send all people
res.json(await People.create(req.body));
} catch (error) {
//send error
res.status(400).json(error);
}
});
// PEOPLE DELETE ROUTE
app.delete("/people/:id", async (req, res) => {
try {
// send all people
res.json(await People.findByIdAndRemove(req.params.id));
} catch (error) {
//send error
res.status(400).json(error);
}
});
// PEOPLE UPDATE ROUTE
app.put("/people/:id", async (req, res) => {
try {
// send all people
res.json(
await People.findByIdAndUpdate(req.params.id, req.body, { new: true })
);
} catch (error) {
//send error
res.status(400).json(error);
}
});
///////////////////////////////
// LISTENER
////////////////////////////////
app.listen(PORT, () => console.log(`listening on PORT ${PORT}`));
Deploy
- Create a git repo in the
backend
foldergit init
- Add all files to staging
git add .
- Commit
git commit -m "message"
- Create a new repo on github.com (make sure its empty and public)
- Add the remote to your local repo
git remote add origin URL
replaceURL
with your repos url - Push up your code
git push origin branchName
replace branch name with your active branch, find that withgit branch
- Go to heroku and create a new project
- Under deploy connect your repo, enable auto deploys, and trigger a manual deploy
- Under settings set your
MONGO_URL
config var - In postman test all your API endpoints
Lab Part 1 - Cheese App
- Create another folder called "Cheese App"
- Create a backend and frontend folder like you did for today's lesson
- Create a cheese API with index, create, update and delete routes
- The model should look like:
name: String,
countryOfOrigin: String,
image: String
- Test the API, deploy the API, test the deployed API