1/1/1970
Express is a Fast, unopinionated, minimalist web framework for Node.js
it is a backend framework like Flask , Django
Resources
Open your project Directory in Terminal and initialize the NodeJS project.
npm init # Interactive project setup.
npm init -y # Quick setup with defaults.
A package.json will be Created.
Now Create Index.js , that would be entry point.
project
βββ index.js
βββ package.json
Install express
npm install express --save # `--save` is optional nowThe --save flag in npm install express --save was used to add the installed package (express in this case) to the dependencies section of your package.json file.
To install all the modules if node_modules folder got deleted, just use npm i
As of npm version 5 this flag is no longer necessary.
Uninstall express
npm uninstall expressExpress is important, Why we can't simply made HTTP server in Nodejs ??index.js and Start Coding:Build A Basic HTTP Server in NodeJS
// Importing the createServer function from the 'node:http' module
const { createServer } = require('node:http');
const hostname = '127.0.0.1';
const port = 3000;
// Creating the server instance using createServer function
const server = createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World');
});
// createServer().listen()
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});Note:
res & req
req and res are the two main objects passed to the callback function of the createServer() method. Here's what they represent:req (Request) -> Represents the incoming request from the client to the server. (Contains information about the request, such as the URL, HTTP method, headers, body data, etc.)res (Response) -> Represents the outgoing response from the server to the client like you to set the response status, headers, and body content that will be sent back to the client.In Express We Can Do the Similar thing β
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})require: in Node.js, require() is a built-in function used to import modules, JSON, and local files into your application
const express = require('express').cjs files or no "type": "module" in package.json).import: this is alternative way to import. This Model is useful if you're working with modern Javascript and want to take advantage of ES Module features.
import express from 'express'.mjs extension or "type":"module" setting or in package.json)if else for Creating different different endpoints. for example \about, \contacts βconst app = express()localhost:3000 will show 'Hello World!' as Response at the Page
app.get('/', (req, res) => {
res.send('Hello World!')
})localhost:3000/about will show 'Introduction' as Response at the Page
app.get('/about', (req, res) => {
res.send('Introduction')
})localhost:3000/contacts will show 'List of Contacts' as Response at the Page
app.get('/contacts', (req, res) => {
res.send('List of Contacts')
})
Note:
In Express, Inspect Network, You will see it will automatically send Status Code like 404. Without Express, we have to write custom codes for Status Codes manually
Express is a Framework to save your time : ) β
Install postman App to Fetch, post HTTP Requests.
Alternatively you can install Thunder Client VS Code Extension if you don't want to switch into different application
Install nodemon It will help the server to restart Automatically when you Save any changes
Import Modules
const express = require('express')
const path = require ('path')
const app = express()
const port = 3000Send Response
// Route Handler
app.get('/', (req, res) => {
res.send('Hello World!')
})Sending HTML as Response
// Route Handler
app.get('/about', (req, res) => {
res.sendFile(path.join(__dirname, 'index.html' ))
})Custom Status Code
// Route Handler
app.get('/contacts', (req, res) => {
res.status(500) // 500: internal error
res.send('List of Contacts')
})Note: res.status() and res.send() ordered matter β
res.send() then res.status() will Note work as expected you call res.send(), the response is sent to the client, which ends the request-response cycle. After that, any further modifications (such as setting the status code) will not be applied because the response has already been sent.Run Server
app.listen(port, () => {
console.log(`app listening at http://localhost:${port}`)
})Note:
${} syntax is part of template literals (or template strings), which allow for easier and more readable string interpolation and multi-line strings. backticks (`) instead of single or double quotesSend JSON
app.get('/about', (req, res) => {
res.json({"gaurav" : 169})
})Note:- You can install chrome extension JSON Formatter if you want to see, the JSON sent in a formatted way. (Useful for big JSON files)
Use html files inside Public Folder
project
βββ node_modules
βββ index.js
βββ public
βββ index.html
const path = require('path')
// All other Imports
// Middleware
app.use(express.static(path.join(__dirname, "public")))
Note:- Now it will start Serving Public Folder as Static Folder
Express Middleware are Functions that will keep Access of Request and Response Objects, and can change it. β
Example to Create your own Middleware
// Create Middleware
const gauravMiddleware = (req, res) =>{
console.log(req)
}
// use Middleware
app.use(gauravMiddleware)In general, there is not need to create Middleware, we only use them : )
Note:
req), the response object (res), and the next middleware function in the application's request-response cycle. βapp.use() is used to define global middleware that works for all routes and HTTP methods.app.get() and other methods like app.post() are used to define route-specific middleware for a particular route (e.g., /hello).Types of Middleware:
app.use() or app.METHOD().express.json() for parsing JSON request bodies.morgan for logging, cors for handling cross-origin requests).Common Built in Middleware
express.json(): Parses incoming JSON data.express.urlencoded(): Parses URL-encoded data (from forms).express.static(): Serves static files like images, CSS, etc.express.Router(): Creates modular route handlers (optionalIf we have more than one middleware, we use next() function, so that next middleware run after current running middleware β
// Create Middleware
const gauravMiddleware = (req, res, next) =>{
console.log(req)
next() // pass control to the next middleware function in the stack.
}
// use Middleware
app.use(gauravMiddleware)// name parameter
app.get('/hello/:name', (req, res) => {
res.send('Hello World! ' + req.params.name)
})
// url -> localhost:3000/hello:Gaurav
// response -> Hello World! GauravWe can fetch blogposts from website, fetch key value pair from your database. You get this by sending the Parameters
static / public folder
static (or public) folder in some frameworks, like Express.js (Node.js) ) folder is used to serve static assets/files to the client, which are files that do not change in response to user input and are sent directly from the server to the client. These files can include: Images, Stylesheets, JavaScript, Fonttemplate folder
template folder (or templates in Flask) is used to store HTML template files that your web application renders. These templates are often dynamically generated with server-side data.express.Router().get() vs express().get()express().get()
const express = require('express');
const app = express();
app.get('/hello', (req, res) => {
res.send('Hello from App!');
});
app.listen(3000, () => console.log('Server is running on port 3000'));/hello.express.Router().get()
const express = require('express');
const app = express();
const router = express.Router();
// express.Router().get()
router.get('/hello', (req, res) => {
res.send('Hello from Router!');
});
// Router use `app.use()`
app.use('/api', router); // Mounting router at '/api'
app.listen(3000, () => console.log('Server is running on port 3000'));/api/hello.Router are mounted on a specific path in the main app using app.use()| Feature | express().Router().get() |
express().get() |
|---|---|---|
| Scope | Local to the router instance. | Global to the app. |
| Reusability | Highly reusable in modular apps. | Not reusable; app-specific. |
| Mounting Required | Yes, using app.use(). |
No, directly available. |
| Preferred Use Case | For modular route management. | For simple apps or global routes. |
public or Static Directory Contains static files that are served directly to the client.
template Directory
project
βββ node_modules
βββ index.js
βββ routes
β βββ blogRoute.js
βββ static
|
βββ templates
| βββ index.html
| βββ blogHome.html
| βββ blogPage.html
βββ data
βββ blogData.js
static Middleware:- Used to serve static files from a specified director
ex:- app.use(express.static('public')); β
Template Rendering:-Used to dynamically generate HTML pages on the server side using template engines.
Create index.js
//index.js
const express = require('express')
const path = require('path')
const app = express()
const port = 3000
app.use(express.static(path.join(__dirname, "static"))) // path.join()β & __dirname
app.use('/', require(path.join(__dirname, `routes/blogRoute.js` )))
app.listen(port, () => {
console.log(`Blog app listening at http://localhost:${port}`)
})The app.use(express.static(path.join(__dirname, "static"))) line in an Express.js application sets up middleware to serve static files from a directory. Hereβs a breakdown of what each part does:
require(path.join(__dirname, 'routes/blogRoute.js')): This loads the router module from the routes/blogRoute.js file. The path.join(__dirname, 'routes/blogRoute.js') constructs the absolute path to the blogRoute.js file. __dirname is a global variable representing the directory name of the current module. β
path.join(__dirname, 'routes/blogRoute.js'): Joins the __dirname (current directory) with the routes/blogRoute.js path, ensuring the path is correctly constructed based on the operating system.
We will separate our other routes from index.js into separate routes files, because it will become complex to write multiple routes into single, index.js. let the routes be routes/blog.js
'/' is the base path where you want to mount your router, require('./routes/blogRoute.js') is the router module that contains the routes and Together, they define that all routes inside blogRoute.js will be mounted at the root path ('/'). β
Note: To ensure your CSS and JavaScript files are applied correctly to your index.html, configure Express to serve static files using app.use('/static', express.static(path.join(__dirname, 'static')));, and use absolute paths in your HTML, such as <link rel="stylesheet" href="/static/style.css" /> and <script src="/static/script.js"></script>. This setup will correctly link your styles and scripts regardless of the file's location.
Create Index.html
...
<body>
This is my Home Page
</body>
...Create blogRoute.js
// blogRoute.js
const express = require('express')
// router function
const router = express.Router()
// routes
router.get('/', (req, res)=>{
res.sendFile(path.join(__dirname, 'templates/index.html' ))
})
// Export router
module.exports = router βNote:
module -> It is an object that represents the current module in a Node.js application.moudle Contains properties like exports, which can be used to expose functions, objects, or values from the module.router.get() vs app.get()β
app.get() is used to define a route handler for a specific HTTP GET request at the application level. (const app = express())router.get() is used to define routes on a router object. Routers allow you to modularize your route definitions, making the application structure cleaner and more manageable. (const router = express.Router())Create blogData.js:
// blogData.js
{
blogs:[
{
title: "How to get started with Python",
content: "This is content",
slug: "python-learn"
},
{
title: "How to get started with JS",
content: "This is content"
},
slug: "javascript-learn"
{
title: "How to get started with Django",
content: "This is content"
},
slug: "python-django-learn"
]
}
// export the file
module.exports blogs;Update blogRouter.js:
const express = require('express')
const router = express.Router()
// inport built in `path` module
const path = require('path')
// import blogData.js file
const blogs = require('../data/blogs')
router.get('/', (req, res)=>{
res.sendFile(path.join(__dirname, `templates/index.html`))
})
// +++++++++++++++++++++++++++++++++++++++++++++++
router.get('/blog', (req, res)=>{
// print each blog title in console
blogs.forEach(elem =>{
console.log(elem.title) β
});
// route '/blog' to 'blogHome.html'
res.sendFile(path.join(__dirname, `templates/blogHome.html` ))
})
// ++++++++++++++++++++++++++++++++++++++++++++++++++++
module.exports = routerNote:
elem => {} is an arrow function in JavaScript.(param)=>{...} -> param => {...}array.forEach(callback(element, index, array), thisArg); where, index, array, & thisArg are optional.If there is a singl Create blogHome.html
<body>
This is my blog Homepage
</body>Create blogPage
<body>
Python Blog
</body>Update blogRoute.js
// blogRoute.js
const express = require('express')
const router = express.Router()
const path = require('path')
const blogs = require('../data/blogs')
router.get('/', (req, res)=>{
res.sendFile(path.join(__dirname, `../templates/index.html` ))
})
router.get('/blog', (req, res)=>{
blogs.forEach(elem =>{
console.log(elem.title)
});
res.sendFile(path.join(__dirname, `../templates/blogHome.html` ))
})
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Individual post routing through Parameter
router.get('/blogpost/:slug', (req, res)=>{
// JS function to Filter the blogs array to find the blog with the matching slug
myBlog = blogs.filter((elem)=>{
return elem.slug == req.params.slug
})
res.sendFile(path.join(__dirname, `../templates/blogPage.html` ))
});
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module.exports = routerThere our basic routing is done, we can Create design and add contents etc.
Note:
slug: A readable, unique identifier for a resource (e.g., blog post).req.params: An object containing route parameters, where req.params.slug is the value of the slug parameter in the URL.elem.slug == req.params.slug, in both slug refer to different things.elem.slug refers to the slug property of the elem object. req.params.slug refers to the dynamic route parameter captured by Express from the URL.Handlebars.js is a templating engine for Node.js that can be used with Express to render web pages from server-side data to the client side.Β Handlebars expressions are the basic unit of a Handlebars template, and are enclosed by double curly braces, {{}} β.Β For example, the following template uses a variable, firstname, enclosed by double curly braces:
template:Β <p>{{firstname}} {{lastname}}</p>
Note: Handlebar is like Jinja2 python template engine.
more template engines for express - EJS, Pug
HBS
HBS (Express-HBS): A specialized package for using Handlebars within the Express framework, making integration with Express easier and more streamlined.
Express-Handlebars** A specialized wrapper for using Handlebars with Express.js, offering better integration and configuration options.
Install express-handlebar: β
npm install express-handlebarsDirectory Structure:
.
βββ app.js
βββ views
βββ home.handlebars
βββ layouts
βββ main.handlebars
2 directories, 3 files
app.js:
Creates a super simple Express app which shows the basic way to register a Handlebars view engine using this package.
import express from 'express';
import { engine } from 'express-handlebars'; // import express-handlebars β
const app = express();
app.engine('handlebars', engine()); // Registers Handlebars as the template engine for Express.
app.set('view engine', 'handlebars'); // Sets Handlebars as the default view engine for rendering templates.
app.set('views', './views');
app.get('/', (req, res) => {
res.render('home');
});
app.listen(3000);res.render('home'): This tells Express to render the home view template (in this case, a file named home.handlebars, or whatever your configured view engine is using).
views/layouts/main.handlebars:
The main layout is the HTML page wrapper which can be reused for the different views of the app.Β {{{body}}} βΒ is used as a placeholder for where the main content should be rendered
...
<body>
{{{body}}}
</body>
...Note:
{{body}} vs. {{{body}}}:{{body}}: This is the standard Handlebars syntax for outputting content. It escapes HTML by default, ensuring that any HTML or JavaScript injected into the body is rendered as plain text (to prevent XSS attacks).{{{body}}}: This is a special Handlebars syntax that does not escape HTML. It directly renders any HTML or JavaScript contained within the body content.
views/home.handlebars:
The content for the app's home view which will be rendered into the layout'sΒ {{{body}}}.
<h1>Example App: Home</h1>
Note: There will be a main.handlebars in /views/layouts directory, that will contain html syntax, and will be reused for different pages like home.handlebars, blogs.handlebars in /view directory.
Including common Content on main.handlebars, This prevent us from making, header, footer and other components copy paste for different pages.
Update index.js
//index.js
const express = require('express')
// import handlebars
var exphbs = require('express-handlebars')
const path = require('path')
const app = express()
const port = 3000
app.engine('handlebars', engine());
app.set('view engine', 'handlebars');
app.use(express.static(path.join(__dirname, "static")))
app.use('/', require(path.join(__dirname, `routes/blogRoute.js` )))
app.listen(port, () => {
console.log(`Blog app listening at http://localhost:${port}`)
})Update blogRoute.js
// blogRoute.js
const express = require('express')
const router = express.Router()
const path = require('path')
const blogs = rquire('../data/blogs')
router.get('/', (req, res)=>{
// handle bar syntax to render `home.handlebars`
res.render('home');
})
router.get('/blog', (req, res)=>{
// handle bar syntax to render `blogHome.handlebars`
res.render('blogHome', {
// <key used in the Handlebars template> : <variable from your Express application containing the data>
blogs: blogs
});
})
router.get('/blogpost/:slug', (req, res)=>{
myBlog = blogs.filter((elem)=>{
return elem.slug == req.params.slug
})
// +++++++++++++++++++++++
res.render('blogPage', {
title: myBlog[0].title,
content: myBlog[0].content})
// myBlog is array so used myBlog[0] to send only one blogPost.
//+++++++++++++++++++++
});
module.exports = router```
Create main.handlebars,
```handlebars
...
<body>
</nav>
...
<a href="/blog"> Blog </a>
...
</nav>
{{{body}}}
</body>
...We added links to route to /blog
Create home.handlebars
this is home.handlebars.Create blogHome.handlebars
{{#each blogs}}
<div class="blog">
<a href="/blogpost/{{this.slug}}"></a>
<h2> {{this.title}}</h2>
</div>
{{/each}}Note: the variables in .handlebars, like blog , this etc are javascript variable comes from the express app
Note: Helpers in Handlebars are custom functions that you can use within your templates to perform operations or transformations on data. They help keep templates clean by moving logic into reusable functions. (e.g., {{#if}}, {{#each}}).
Create blogPage.handlebars (Page for Each Posts)
<h2>{{title}}</h2>
<p>
{{content}}
</p>This was the Basic Structure of the blog post
Final blog App, File Directory Structures
project
βββ index.js
βββ routes
β βββ blogRoute.js
βββ views
βββ home.handlebars
βββ bloghome.handlebars
βββ blogPage.handlebars
βββ layouts
βββ main.handlebars
Remaining video is on hosting
DigitalOcean is a cloud computing service provider that offers scalable virtual servers known as Droplets. Droplets are customizable virtual private servers (VPS) used for hosting applications, websites, and databases. DigitalOcean provides a user-friendly platform with features like pre-configured server images, managed databases, and scalable resources.
Create a Droplet:
Set Up Your Server:
scp, Git, or FTP).Install Dependencies:
npm install to install dependencies.Run Your Express App:
node app.js or a process manager like PM2 (pm2 start app.js).Configure a Reverse Proxy (optional but recommended):
Set Up a Domain and SSL (optional):
This setup allows you to deploy and manage your Express application on a reliable cloud platform.
β Completed