Express
| Created | |
|---|---|
| Type | Library |
| Language | Javascript |
| Last Edit |
Description
Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.
Express 4.x - API Reference (expressjs.com)
Setup
Express Application
Import and call express function to create a new express application
const express = require("express");
const app = express();Parse JSON
app.use(express.json());This will by default parse json so that json is accessible as objects.
Routes
app.com:
app.get("", (req, res) => {
res.send("Hello Express!");
});app.com/help
app.get("/help", (req, res) => {
res.send("Help Page");
});404
app.get("/help/*", (req, res) => {
res.send("Help article not found")
});
app.get("*", (req, res) => {
res.send("My 404 page");
});Listen
app.listen(3000, () => {
console.log("Server is up on port 3000.");
});Cors Options
Setup allowed origins and credentials requirement.
import cors from "cors";
const allowedOrigins = [
"http://localhost:3000",
"https://course-authoring-frontend-testing.onrender.com",
];
var corsOptions = {
credentials: true,
origin: allowedOrigins,
};
app.use(cors(corsOptions));Hot Reload with Nodemon
Starting node app with following command will restart server whenever new changes are saved.
nodemon src/app.jsReturn Data
HTML
app.get("", (req, res) => {
res.send("<h1>Weather</h1>");
});JSON
app.get("/help", (req, res) => {
res.send({ name: "Andrew", age: 27 });
});Static HTML Files
Files to be served are stored outside of src folder in public directory.
index.html, about.html, help.html stored in public folder
const path = require("path");
const express = require("express");
const app = express();
const publicDirectory = path.join(__dirname, "../public");
app.use(express.static(publicDirectory));Visiting localhost:3000 will serve index.html and localhost:3000/about.html will serve about.html and so on.
Dynamic HTML Files
Using templating engine handlebars for express called hbs
npm i hbsSetup express to use hbs:
app.set("view engine", "hbs");Create a folder in root of project called views. It will contain dynamic files with extension .hbs
If views contain index.hbs file then render it for certain route with required data.
app.get("", (req, res) => {
res.render("index", { title: "Weather App" });
});index.hbs:
<html>
<head>
<link rel="stylesheet" href="/css/styles.css" />
<script src="/js/app.js"></script>
<title>Weather App</title>
</head>
<body>
<h1>{{title}}</h1>
</body></html>CSS and JS files will be inside public folder but files in views can access them without mentioning the whole path.
Handling Requests
Get Request
params in req in get variable specified.app.get("/users/:id", async (req, res) => {
const _id = req.params.id;
});Post Request
res.send to send data back.app.post("/users", async (req, res) => {
const body = req.body;
res.send(body);
});Patch Request
app.patch("/users/:id", async (req, res) => {
const _id = req.params.id;
});Delete Request
app.delete("/users/:id", async (req, res) => {
const _id = req.params.id;
});Validation
How To Use Joi for Node API Schema Validation | DigitalOcean
Status Codes
200
app.post("/users", async (req, res) => {
const user = new User(req.body);
try {
await user.save();
res.status(200).send(user);
}
});400
app.post("/users", async (req, res) => {
const user = new User(req.body);
try {
await user.save();
res.status(200).send(user);
}
catch (e) {
res.status(400).send(e);
}
});500
app.get("/users/:id", async (req, res) => {
const _id = req.params.id;
try {
if (condition) {
res.send(resData);
} else {
throw new Error("Invalid ID");
}
} catch (error) {
res.status(500).send(error.message);
}
});Router
User Router
const express = require("express");
const router = new express.Router();
router.get("/user", (req, res) => {
res.send("This is from my other router");
});
//... all other methods related to user here
module.exports = router;Use Routes
const express = require("express");
const userRouter = require("./routers/user");
const taskRouter = require("./routers/task");
const app = express();
const port = process.env.PORT || 8000;
app.use(express.json());
app.use(userRouter); //user router
app.use(taskRouter); //task router
app.listen(port, () => {
console.log("Server is up on port " + port);
});Middleware
Middleware will allows up to make all the necessary routes (requests) authenticated, so that Express will only accept those requests with an authorisation token in the header.
Middleware will run once a new request has come in and before the route handler is run.
app.use((req, res, next) => {
if (req.method === "GET") {
res.send("GET requests are disabled");
} else {
next();
}
});Middlewares should be defined above all other app.use statements.
Maintenance Mode
app.use((req, res, next) => {
res.status(503).send("Server In Maintenance Mode");
next();
});File Upload
npm i multer
const multer = require("multer");
const upload = multer({
dest: "images",
});
app.post("/upload", upload.single("upload"), (req, res) => {
res.send();
});Validation
File Size Limit
const upload = multer({
dest: "avatars",
limits: {
fileSize: 1000000,
//in bytes: 1MB
},
});
File Type (Extension)
const upload = multer({
dest: "avatars",
limits: {
fileSize: 1000000, //in bytes: 1MB
},
fileFilter(req, file, callback) {
if (!file.originalname.match(/\.(jpg|jpeg|png)$/)) {
return callback(new Error("Please upload an image"));
}
callback(undefined, true);
},
});
Error Handling
router.post(
"/users/profile/avatar",
auth,
upload.single("avatar"),
async (req, res) => {
res.send();
},
(error, req, res, next) => {
res.status(400).send({ error: error.message });
}
);Upload To Database
Remove dest from multer
const upload = multer({
limits: {
fileSize: 1000000, //in bytes: 1MB
},
fileFilter(req, file, callback) {
if (!file.originalname.match(/\.(jpg|jpeg|png)$/)) {
return callback(new Error("Please upload an image"));
}
callback(undefined, true);
},
});Route Handler:
router.post(
"/users/profile/avatar",
auth,
upload.single("avatar"),
async (req, res) => {
req.user.avatar = req.file.buffer;
await req.user.save();
res.send();
},
(error, req, res, next) => {
res.status(400).send({ error: error.message });
}
);Render Image From Binary in HTML
<img src=”data:image/jpg;base64,BINARYSTRINGHERE" />
Image Resize & File Type
Resizing and converting image file before saving the binary in database.
const sharp = require("sharp");
const buffer = await sharp(req.file.buffer)
.resize({ widht: 250, height: 250 })
.png()
.toBuffer();
req.user.avatar = buffer;
await req.user.save();
res.send();File Serve
router.get("users/:id/avatar", async (req, res) => {
const _id = req.params.id;
try {
if (mongoose.Types.ObjectId.isValid(_id)) {
const user = await User.findById(_id);
if (!user || !user.avatar) {
throw new Error();
}
res.set("Content-Type", "image/jpg");
res.send(user.avatar);
} else {
throw new Error("Invalid ID");
}
} catch (error) {
res.status(400).send();
}
});Visiting {{host}}/users/636b34ec6b3026c9da4d4acf/avatar from browser will get the avatar of that particular user.
Also this URL can be set as src attribute of img tag to render the image.

