12/27/24, 12:03 PM Projects | 100xDevs
HTTP Deep dive 1 of 9
Recap
Last week, we understood about HTTP Servers
Jargon from last week
1. Domain name/IP
2. Port
3. Methods
4. Plaintext vs JSON vs HTML response
5. Status codes
6. Body
7. Routes
8. Express
What we’re learning today
1. Headers
2. Fetch API in the browser
3. Query params, Creating our own HTTP Server (Again). Does simple math
(sum server)
4. Middlewares
1. Create a middleware function that logs each incoming request’s HTTP
method, URL, and timestamp to the console
2. Count total number of requests
5. Commonly used middlewares
1. express.json / bodyParser.json
https://projects.100xdevs.com/pdf/http-deep-dive/HTTP-Deep-dive-1 1/17
12/27/24, 12:03 PM Projects | 100xDevs
2. cors
HTTP Deep dive 1 of 9
Headers
HTTP headers are key-value pairs sent between a client (like a web
browser) and a server in an HTTP request or response. They convey
metadata about the request or response, such as content type, auth
information etc.
Common headers
1. Authorization (Sends the user auth information)
2. Content-Type - Type of information client is sending (json, binary etc)
3. Referer - Which URL is this request coming from
Request headers
The headers the client sends out in the request are known as request
headers
Response headers
The headers that the server responds with are known as the response
headers.
https://projects.100xdevs.com/pdf/http-deep-dive/HTTP-Deep-dive-1 2/17
12/27/24, 12:03 PM Projects | 100xDevs
HTTP Deep dive 1 of 9
Fetch API
There are 2 high level ways a browser can send requests to an HTTP server:
1. From the browser URL (Default GET request):
When you type a URL into the browser’s address bar and press
Enter, the browser sends an HTTP GET request to the server. This
request is used to retrieve resources like HTML pages, images, or
other content.
2. From an HTML form or JavaScript (Various request types):
HTML Forms: When a user submits a form on a webpage, the
browser sends an HTTP request based on the form’s method
attribute, which can be GET or POST . Forms with method="POST"
typically send data to the server for processing (e.g., form
submissions).
JavaScript (Fetch API): JavaScript running in the browser can
make HTTP requests to a server using APIs the fetch API. These
requests can be of various types ( GET , POST , PUT , DELETE , etc.)
and are commonly used for asynchronous data retrieval and
manipulation (e.g., AJAX requests).
Fetch request examples
Server to send the request to -
https://jsonplaceholder.typicode.com/posts/1 (GET request)
https://projects.100xdevs.com/pdf/http-deep-dive/HTTP-Deep-dive-1 3/17
12/27/24, 12:03 PM Projects | 100xDevs
<!DOCTYPE html>
HTTP Deep dive 1 of 9
<html>
<body>
<div id="posts"></div>
<script>
async function fetchPosts() {
const res = await fetch("https://jsonplaceholder.typicode.com/posts/1");
const json = await res.json();
document.getElementById("posts").innerHTML = json.title;
}
fetchPosts();
</script>
</body>
</html>
Using axios (external library)
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.7.6/axios.min.js"></
</head>
<body>
<div id="posts"></div>
<script>
async function fetchPosts() {
const res = await axios.get("https://jsonplaceholder.typicode.com/posts/1")
document.getElementById("posts").innerHTML = res.data.title;
}
fetchPosts();
</script>
</body>
</html>
https://projects.100xdevs.com/pdf/http-deep-dive/HTTP-Deep-dive-1 4/17
12/27/24, 12:03 PM Projects | 100xDevs
HTTP Deep dive 1 of 9
Create an HTTP Server
It should have 4 routes
1. http://localhost:3000/multiply?a=1&b=2
2. http://localhost:3000/add?a=1&b=2
3. http://localhost:3000/divide?a=1&b=2
4. http://localhost:3000/subtract?a=1&b=2
Inputs given at the end after ? are known as query parameters (usually
used in GET requests)
The way to get them in an HTTP route is by extracting them from the req
argument (req.query.a , req.query.b)
Steps to follow
Initialize node project
npm init -y
Install dependencies
npm install express
Create an empty index.js
touch index.js
Write the code to create 4 endpoints
const express = require("express");
const app = express();
https://projects.100xdevs.com/pdf/http-deep-dive/HTTP-Deep-dive-1 5/17
12/27/24, 12:03 PM Projects | 100xDevs
app.get("/sum", function(req, res) {
HTTP Deep dive 1 of 9
});
app.get("/multiply", function(req, res) {
});
app.get("/divide", function(req, res) {
});
app.get("/subtract", function(req, res) {
});
app.listen(3000);
Fill in the handler body
const express = require("express");
const app = express();
app.get("/sum", function(req, res) {
const a = req.query.a;
const b = req.query.b;
res.json({
ans: a + b
})
});
app.get("/multiply", function(req, res) {
const a = req.query.a;
const b = req.query.b;
res.json({
ans: a * b
})
});
app.get("/divide", function(req, res) {
const a = req.query.a;
const b = req.query.b;
https://projects.100xdevs.com/pdf/http-deep-dive/HTTP-Deep-dive-1 6/17
12/27/24, 12:03 PM Projects | 100xDevs
res.json({
HTTP
ans:Deep
a / bdive 1 of 9
})
});
app.get("/subtract", function(req, res) {
const a = req.query.a;
const b = req.query.b;
res.json({
ans: a - b
})
});
app.listen(3000);
Test it in the browser
💡What do you think is wrong here?
Correct the solution
const express = require("express");
const app = express();
app.get("/sum", function(req, res) {
const a = parseInt(req.query.a);
const b = parseInt(req.query.b);
res.json({
ans: a + b
})
});
app.get("/multiply", function(req, res) {
const a = req.query.a;
const b = req.query.b;
res.json({
ans: a * b
})
});
https://projects.100xdevs.com/pdf/http-deep-dive/HTTP-Deep-dive-1 7/17
12/27/24, 12:03 PM Projects | 100xDevs
app.get("/divide", function(req, res) {
HTTP Deep
const dive 1 of 9
a = req.query.a;
const b = req.query.b;
res.json({
ans: a / b
})
});
app.get("/subtract", function(req, res) {
const a = parseInt(req.query.a);
const b = parseInt(req.query.b);
res.json({
ans: a - b
})
});
app.listen(3000);
Middlewares
In Express.js, middleware refers to functions that have access to the request
object ( req ), response object ( res ), and the next function in the
application's request-response cycle. Middleware functions can perform a
variety of tasks, such as
1. Modifying the request or response objects.
2. Ending the request-response cycle.
3. Calling the next middleware function in the stack.
Try running this code and see if the logs comes or not
https://projects.100xdevs.com/pdf/http-deep-dive/HTTP-Deep-dive-1 8/17
12/27/24, 12:03 PM Projects | 100xDevs
HTTP Deep dive 1 of 9
app.use(function(req, res, next) {
console.log("request received");
next();
})
app.get("/sum", function(req, res) {
const a = parseInt(req.query.a);
const b = parseInt(req.query.b);
res.json({
ans: a + b
})
});
Modifying the request
app.use(function(req, res, next) {
req.name = "harkirat"
next();
})
app.get("/sum", function(req, res) {
console.log(req.name);
const a = parseInt(req.query.a);
const b = parseInt(req.query.b);
res.json({
ans: a + b
})
});
Ending the request/response cycle
app.use(function(req, res, next) {
res.json({
message: "You are not allowed"
})
})
https://projects.100xdevs.com/pdf/http-deep-dive/HTTP-Deep-dive-1 9/17
12/27/24, 12:03 PM Projects | 100xDevs
app.get("/sum", function(req, res) {
HTTP Deep dive 1 of 9
console.log(req.name);
const a = parseInt(req.query.a);
const b = parseInt(req.query.b);
res.json({
ans: a + b
})
});
Calling the next middleware function in the stack.
app.use(function(req, res, next) {
console.log("request received");
next();
})
app.get("/sum", function(req, res) {
const a = parseInt(req.query.a);
const b = parseInt(req.query.b);
res.json({
ans: a + b
})
});
Route specific middlewares
Route-specific middleware in Express.js refers to middleware functions that
are applied only to specific routes or route groups, rather than being used
globally across the entire application
const express = require('express');
const app = express();
https://projects.100xdevs.com/pdf/http-deep-dive/HTTP-Deep-dive-1 10/17
12/27/24, 12:03 PM Projects | 100xDevs
// Middleware function
HTTP Deep
function dive 1 of 9
logRequest(req, res, next) {
console.log(`Request made to: ${req.url}`);
next();
}
// Apply middleware to a specific route
app.get('/special', logRequest, (req, res) => {
res.send('This route uses route-specific middleware!');
});
app.get("/sum", function(req, res) {
console.log(req.name);
const a = parseInt(req.query.a);
const b = parseInt(req.query.b);
res.json({
ans: a + b
})
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
💡Only the /special endpoint runs the middleware
Assignments on middleware
Try these out yourself.
1. Create a middleware function that logs each incoming request’s HTTP
method, URL, and timestamp to the console
https://projects.100xdevs.com/pdf/http-deep-dive/HTTP-Deep-dive-1 11/17
12/27/24, 12:03 PM Projects | 100xDevs
2. Create
HTTPaDeep
middleware
dive 1 of 9 that counts total number of requests sent to a
server. Also create an endpoint that exposes it
Commonly used
middlewares
https://projects.100xdevs.com/pdf/http-deep-dive/HTTP-Deep-dive-1 12/17
12/27/24, 12:03 PM Projects | 100xDevs
Through your journey of writing express servers , you’ll find some commonly
HTTP Deep dive 1 of 9
available (on npm) middlewares that you might want to use
1. express.json
The express.json() middleware is a built-in middleware function in Express.js
used to parse incoming request bodies that are formatted as JSON. This
middleware is essential for handling JSON payloads sent by clients in POST
or PUT requests.
const express = require('express');
const app = express();
// Use express.json() middleware to parse JSON bodies
app.use(express.json());
// Define a POST route to handle JSON data
app.post('/data', (req, res) => {
// Access the parsed JSON data from req.body
const data = req.body;
console.log('Received data:', data);
// Send a response
res.send('Data received');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
💡Try converting the calculator assignment to use POST endpoints.
Check if it works with/without the express.json middleware
💡Express uses bodyParser under the hood -
https://github.com/expressjs/express/blob/master/lib/express.js#L
78C16-L78C26
https://projects.100xdevs.com/pdf/http-deep-dive/HTTP-Deep-dive-1 13/17
12/27/24, 12:03 PM Projects | 100xDevs
HTTP Deep dive 1 of 9
cors - Cross origin resource
sharing
Cross-Origin Resource Sharing (CORS) is a security feature implemented
by web browsers that controls how resources on a web server can be
requested from another domain. It's a crucial mechanism for managing
cross-origin requests and ensuring secure interactions between different
origins on the web.
Cross origin request from the browser
Same request from Postman
Real world example
Create an HTTP Server
Create an HTTP Server
const express = require("express");
const app = express();
app.get("/sum", function(req, res) {
console.log(req.name);
const a = parseInt(req.query.a);
const b = parseInt(req.query.b);
https://projects.100xdevs.com/pdf/http-deep-dive/HTTP-Deep-dive-1 14/17
12/27/24, 12:03 PM Projects | 100xDevs
HTTP Deep dive 1 of 9
res.json({
ans: a + b
})
});
app.listen(3000);
Create an index.html file (public/index.html)
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.7.6/axios.min.js"></
</head>
<body>
<div id="posts"></div>
<script>
async function sendRequest() {
const res = await axios.get("http://localhost:3000/sum?a=1&b=2");
}
sendRequest();
</script>
</body>
</html>
Serve the HTML File on a different port
cd public
npx serve
💡You will notice the cross origin request fails
Add cors as a dependency
npm i cors
Use the cors middleware
https://projects.100xdevs.com/pdf/http-deep-dive/HTTP-Deep-dive-1 15/17
12/27/24, 12:03 PM Projects | 100xDevs
const
HTTPexpress = require("express");
Deep dive 1 of 9
const cors = require("cors");
const app = express();
app.use(cors());
app.get("/sum", function(req, res) {
console.log(req.name);
const a = parseInt(req.query.a);
const b = parseInt(req.query.b);
res.json({
ans: a + b
})
});
app.listen(3000);
You dont need cors if the frontend and backend
are on the same domain
Try serving the frontend on the same domain
const express = require("express");
const app = express();
app.get("/sum", function(req, res) {
console.log(req.name);
const a = parseInt(req.query.a);
const b = parseInt(req.query.b);
res.json({
ans: a + b
})
});
app.get("/", function(req, res) {
res.sendFile(__dirname + "/public/index.html");
});
app.listen(3000);
https://projects.100xdevs.com/pdf/http-deep-dive/HTTP-Deep-dive-1 16/17
12/27/24, 12:03 PM Projects | 100xDevs
Go to localhost:3000 , notice that the underlying request doesnt fail with
HTTP Deep dive 1 of 9
cors (even though we don’t have the cors middleware)
https://projects.100xdevs.com/pdf/http-deep-dive/HTTP-Deep-dive-1 17/17