Repository for getting acquainted with express JS.
- Fast , unopinionated , minimalistic web framework for Node.js
- Server-Side framework
- Combined with React JS, Angular JS to build full stack applications
- Makes Node.js application easier
- Used for both server rendered applications and API/Microservices
- Fast, light, free
- Full control of request and response
- JS, ES6
- Basic Node.js and npm(node package manager)
- Node.js
- Postman
const express = require('express');
//Init Express
const app = express();
//Create endpoints/route handlers
app.get('/', function(req,res) {
res.send('Hello Bilahi');
});
//Listen to a port
app.listen(8000);
- The require() method is used to load and cache JavaScript modules. So here it is used to bring express to the top.
- To initialise express we put the express() method to a variable usually called app.
- We are accepting a Get request to the index route '/' and we use a callback function.
- Responding with a text hello world.
- Listening to the port 8000.
- http://localhost:8000/ Will show the response of get request.
app.get('/', function(req,res) {
//Fetch from database
//MongoDB, mySQL, etc can be used
//Load Pages
//Return JSON Data
//Full access to Request and Response
});
- Request object - HTTP Request parameters - URLparameters, query
- Response object - HTTP Response - Send back JSON Data, Render a template, redirect etc
- We can parse incoming data with Body Parser
- No need to store routes in one file. Express has a router that can store routes in seperate files and export them
- Middleware functions are functions which have access to request and response object.
- Express has built in middleware.
- Middleware also third party.
- Custom Middleware - Making changes to request and response object, Ending response cycle, Calling next middleware in the stack,
- Create package.json
npm init
- Install express
npm i express
- Create index.js
- Install nodemon for auto update of server
npm i nodemon
const express = require("express");
const app = express();
const PORT = process.env.PORT || 8000;
app.listen(PORT, () => console.log("Server Started"));
const express = require("express");
const app = express();
app.get("/", (req, res) => {
res.send("Responding to request <br><h1>Hello World </h1>");
});
const PORT = process.env.PORT || 8000;
app.listen(PORT, () => console.log("Server Started"));
- Everytime anything is changed the server needs to be stopped and restarted
- For the above problem - Install nodemon
npm i -D nodemon
-D
in the above code is we want nodemon development only it will not work in production.- After installation change scripts in package.json
"scripts": {
"start": "node index",
"dev": "nodemon index"
},
- Start the server
npm run dev
const express = require("express");
const path = require("path");
const app = express();
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname, "public", "index.html"));
});
const PORT = process.env.PORT || 8000;
app.listen(PORT, () => console.log("Server Started"));
const express = require("express");
const path = require("path");
const app = express();
//Set Static folder
app.use(express.static(path.join(__dirname, "public")));
const PORT = process.env.PORT || 8000;
app.listen(PORT, () => console.log("Server Started"));
- Just works like a static site with contents inside public folder
const members = [
{
id: 1,
name: "Madara Uchiha",
email: "[email protected]",
status: "active",
},
{
id: 2,
name: "Obito Uchiha",
email: "[email protected]",
status: "inactive",
},
{
id: 3,
name: "Kakashi Hatake",
email: "[email protected]",
status: "active",
},
];
app.get("/api/members", (req, res) => {
res.json(members);
});
- We want to return this json when we hit route
- This can be done by react or angular or in postman
- POSTMAN is used here to hit the route and get the members
const moment = require("moment");
const logger = (req, res, next) => {
console.log(
`${req.protocol}://${req.get("host")}${
req.originalUrl
}: ${moment().format()}`
);
next();
};
module.exports = logger;
- We are creating a middleware function logger that takes in (req, res, next)
- We are loging the URL thats hit and the date.
- The URL is access is using request object
req.protocol
this will give us HTTP, Then we type://
and get the hostreq.get("host")
after that we get the original URLreq.originalUrl
. - If we go to postman and send a request and look in the console. We'd get the whole URL that's hit.
http://localhost:5000/api/members
- For date install moment using npm
npm i moment
and require is usingrequire()
method at the top. ${moment().format()}
gives the date
app.get("/api/members/:id", (req, res) => {
res.json(members.filter((member) => member.id === parseInt(req.params.id)));
});
- req.params.id is string so we need to parseInt() it to match the data type of member ID from database
//Get Single Member
app.get("/api/members/:id", (req, res) => {
const found = members.some((member) => member.id === parseInt(req.params.id));
if (found) {
res.json(members.filter((member) => member.id === parseInt(req.params.id)));
} else {
res.status(400).json({ msg: `No Member with the ID of ${req.params.id}` });
}
});
req.status(400)
- Gives 400 Bad Request with the message incuded injson({msg:})
Note -
- Having all the routes in a single file might get messy.
- We move all the routes to a folder - router>api>members.js
- In order to use the routes we need to require express and router at the top
const express = require('express')
const router = express.Router()
const members = require("../../Members");
../../
is to get out of api>routes and and into the main root because our Members database is in that folder- In our index.js we replace the routes with
app.use("/api/members", require("./routes/api/members"));
- Since we are using
/api/members
in our index.js app.use code we can replace/api/members
in routes which are in routes folder with/
.
When we add something or create something to the server - POST request
- use
router.post
router.post("/", (req, res) => {
const newMember = {
res.send(req.body)
};
/
to hit theapi/members
(req,res) => {}
callback function- uuid is a npm package that generates a random user id
npm i uuid
and bring it in our membersconst uuid = require('uuid')
- To parse the data we are sending in we need a body parser
//body parser middleware
app.use(express.json())
app.use(express.urlencoded(extended: false))
Now -
//Create Member
router.post("/", (req, res) => {
const newMember = {
id: uuid.v4(),
name: req.body.name,
email: req.body.email,
status: "active",
};
if (!newMember.name || !newMember.email) {
return res.status(400).json({ msg: "Please include a name and email" });
}
members.push(newMember);
res.json(members);
});
- For the name property, we'll get that from the request body
req.body.name
- For the email
req.body.email
- Then we push the newMember in our hardcoded database(array) and return the whole array
When we have to update something on the server - PUT Request
//Update Member
router.put("/:id", (req, res) => {
const found = members.some((member) => member.id === parseInt(req.params.id));
if (found) {
const updMember = req.body;
members.forEach((member) => {
if (member.id === parseInt(req.params.id)) {
member.name = updMember.name ? updMember.name : member.name;
member.email = updMember.email ? updMember.email : member.email;
res.json({ msg: "Member Updated", member });
}
});
} else {
res.status(400).json({ msg: `No Member with the ID of ${req.params.id}` });
}
});
- We are creating the const updMember to get the email and name by
req.body
- Then we loop through the members we have and check to see if it matches the id, if it does, we update. The problem is they might update the email and not the name or vise versa, so we would check if the name and email are actually sent, so we'll use ternary operator
In POSTMAN
- Change Header - Content-Type application/json
- Body - raw - make the new changes
- In Delete we will use filte but not
!==
to filter out the one with the id. - In POSTMAN and make a Delete request
http://localhost:8000/api/members/1
- It will show the members besides the one with ID 1
//Delete Member
router.delete("/:id", (req, res) => {
const found = members.some((member) => member.id === parseInt(req.params.id));
if (found) {
res.json(members.filter((member) => member.id !== parseInt(req.params.id)));
} else {
res.status(400).json({ msg: `No Member with ID ${req.params.id}` });
}
});
Express Handlebars
Express Handlebars Documentation
- Inside views>layouts>main.handlebars - Bootstrap CDN is included
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Example App</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
</head>
<body>
<div class="container mt-4">
{{{body}}}
</div>
</body>
</html>
- To add a view to home page - Create a file index.handlebars inside views>index.handlebards we add the html code
<h1 class="text-center mb-3">{{title}}</h1>
- title is a variable and it has to be included within double {{}}. Variable is initialised in index.js
//Home Page
app.get("/", (req, res) => {
res.render("index", {
title: "Member App",
});
});
- Add members from our database array to the home page
index.js
//Home Page
app.get("/", (req, res) => {
res.render("index", {
title: "Member App",
members,
});
});
index.handlebars
<h1 class="text-center mb-3">{{title}}</h1>
<h4>Members</h4>
<ul class="list-group">
{{#each members}}
<li class="list-group-item">{{this.name}}:{{this.email}}</li>
{{/each}}
</ul>
The End !>_<