Question 2
Question 2
Web development typically involves two primary areas of functionality: client-side and server-
side. Both are essential in delivering dynamic, interactive, and efficient applications, but they
operate in different environments and serve different purposes. Understanding the distinction
between them is crucial for developers, as it directly impacts performance, security, and user
experience.
1. Definitions
Client-side Application
A client-side application is one where most of the code is executed on the user's device (i.e., the
client). This includes HTML, CSS, and JavaScript that run in the web browser. These applications
are responsible for rendering the user interface (UI), handling interactions, and often making
asynchronous requests (like using AJAX or Fetch API) to fetch or send data.
Example: A Single Page Application (SPA) built with React.js or Angular.
Server-side Application
A server-side application is executed on a web server. It handles business logic, database
interactions, authentication, and generates dynamic content to be sent to the client. The client
receives HTML pages that are rendered on the server before being sent.
Example: An application built with Express.js, Django, or PHP where most of the logic runs on the
server.
2. Execution Environment
• Client-side:
• Executes in the browser.
• Utilizes the resources (CPU, memory) of the client’s device.
• Dependent on browser compatibility and performance.
• Server-side:
• Executes on a centralized server.
• Uses server resources for processing.
• The same output can be generated regardless of client browser.
3. Technologies Used
• Client-side:
• HTML, CSS, JavaScript
• Frontend frameworks/libraries: React.js, Angular, Vue.js, Svelte
• Server-side:
• Programming languages: JavaScript (Node.js), Python, Java, PHP, Ruby, etc.
• Frameworks: Express.js, Django, Spring, Laravel, Ruby on Rails
5. Performance Considerations
• Client-side rendering can reduce server load and provide faster interactivity after the initial
load. However, the first page load might be slower due to heavy JavaScript bundles. It also
depends on the client’s hardware.
• Server-side rendering usually delivers fully formed HTML to the browser quickly,
improving perceived load time and SEO. However, it increases the server load and response
time for dynamic pages.
6. Security
Security is a major distinction:
• Client-side:
• Vulnerable to XSS (Cross-Site Scripting) attacks.
• Code is exposed and can be inspected/modified using browser developer tools.
• Should never handle sensitive operations like password hashing or database access.
• Server-side:
• Can implement strong security protocols (authentication, authorization).
• Logic and sensitive data are kept private.
• Vulnerable to server-side attacks like SQL Injection, but easier to manage securely.
8. Examples
Client-side App Example:
A weather forecast SPA built with React fetches real-time data from an API and updates the UI
dynamically without reloading the page.
1. What is Node.js?
Node.js is a JavaScript runtime environment that allows you to run JavaScript code outside the
browser — on the server or your computer.
Key Features:
• Allows building fast and scalable network applications.
• Used in backend development with frameworks like Express.js.
• Supports file system operations, server creation, databases, etc.
2. What is NPM?
NPM stands for Node Package Manager. It comes installed with Node.js and is used to:
• Install open-source libraries (called packages or modules).
• Manage project dependencies.
• Share your own code with others (if needed).
node -v
npm -v
If both commands return version numbers, it means Node.js and NPM are installed successfully.
4. Setting Up a New Web Project
Step 1: Create a Project Folder
mkdir my-web-project
cd my-web-project
npm init
This will ask you a series of questions like project name, version, description, etc. You can press
Enter to accept the defaults.
5. Understanding package.json
The package.json file stores important information about your project:
{
"name": "my-web-project",
"version": "1.0.0",
"description": "A simple web project",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {},
"devDependencies": {}
}
6. Installing Dependencies
Let’s say you want to create a simple web server using Express, a popular Node.js framework.
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000');
});
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js"
}
Now run:
Your server will restart automatically whenever you change and save the file — useful during
development!
8. node_modules and package-lock.json
• node_modules/: This folder contains all installed packages. It can be large and is not shared
in code repositories.
• package-lock.json: This file keeps track of the exact version of each installed package. It
ensures consistency when your project is installed on other machines.
• Others can run npm install to install all dependencies based on package.json.
• Uninstall a package:
mkdir simple-server
cd simple-server
// server.js
const http = require('http');
const fs = require('fs');
const path = require('path');
server.listen(3000, () => {
console.log('Server running at http://localhost:3000');
});
Optional: Create a 404 Page
Create a file called 404.html:
Now your server shows the correct file based on the URL.
3. Based on the URL, your server reads a file from your computer (like index.html).
4. The server sends back the file content as the HTTP response.
5. The browser displays the page.
1. What is Express.js?
Express.js is a web application framework for Node.js. It provides tools and features to handle:
• Routing (which URL should return what)
• Middleware (functions that run before sending a response)
• Serving static files (HTML, CSS, images)
• Request and response handling
• Error handling
• Creating REST APIs
// Define a route
app.get('/', (req, res) => {
res.send('Hello from Express!');
});
• You can also use app.post(), app.put(), app.delete() for other HTTP methods.
✅ 2. Serving Static Files
To serve HTML, CSS, or image files easily:
js
CopyEdit
app.use(express.static('public'));
Now, put your static files (like index.html, style.css, logo.png) in the public folder.
Express will automatically serve them when requested.
Example:
• http://localhost:3000/style.css will return public/style.css
✅ 3. Middleware Support
Middleware are functions that run between the request and response.
For example, to log every request:
js
CopyEdit
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next(); // Pass control to the next handler
});
Go to http://localhost:3000/api/products
You’ll see a JSON response with product data.
In your server:
<h1>Welcome Alice</h1>
✅ 4. Centralized Control
• All logic and rendering happen on the server.
• Easier to manage when working with data from a database.
✅ 5. Reusable Templates
• Create a base layout and reuse it for different pages.
• This keeps your code clean and reduces duplication.
Example of a layout (EJS):
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
Now, when you visit http://localhost:3000, you’ll see the rendered HTML page.
Example:
Static:
<h1>Welcome!</h1>
Dynamic:
<h1>Welcome, Alice!</h1>
We need some way to insert the name "Alice" into the HTML. That’s where a templating engine
comes in.
mkdir express-dynamic
cd express-dynamic
npm init -y
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
In views/products.ejs:
<!DOCTYPE html>
<html>
<head>
<title>Product List</title>
</head>
<body>
<h1>Products</h1>
<ul>
<% products.forEach(product => { %>
<li><%= product.name %> - Rs. <%= product.price %></li>
<% }); %>
</ul>
</body>
</html>
Result in Browser:
Products
- Pen - Rs. 10
- Notebook - Rs. 50
- Pencil - Rs. 5
This is dynamic content: the page is changing based on the data sent from the server.
✅ Reuse templates
You can create a layout file (like a master page) and reuse it for many pages.
5. Folder Structure
Here’s how your project might look:
express-dynamic/
│
├── server.js
├── package.json
└── views/
├── home.ejs
└── products.ejs
Later, you can also create a public/ folder for CSS and images.
1. What is an API?
API stands for Application Programming Interface. In web development, it usually means a
URL you can access to get or send data.
Example of a public API:
https://jsonplaceholder.typicode.com/users
This API returns a list of users in JSON format.
2. What is JSON?
JSON (JavaScript Object Notation) is a way to store and exchange data. It looks like JavaScript
objects.
Example:
{
"name": "Alice",
"age": 25,
"email": "[email protected]"
}
JSON is easy for both humans and computers to read. That’s why many APIs use it to send and
receive data.
3. What is fetch() in JavaScript?
The fetch() function lets you make HTTP requests in JavaScript.
Basic syntax:
fetch(url)
.then(response => response.json())
.then(data => {
// use the data here
})
.catch(error => {
// handle any errors
});
https://jsonplaceholder.typicode.com/users
<!DOCTYPE html>
<html>
<head>
<title>Fetch Example</title>
</head>
<body>
<h1>User List</h1>
<ul id="userList"></ul>
<script>
// Step 1: Fetch data from API
fetch('https://jsonplaceholder.typicode.com/users')
.then(response => response.json()) // Step 2: Convert response to JSON
.then(data => {
// Step 3: Use the data
const userList = document.getElementById('userList');
data.forEach(user => {
const li = document.createElement('li');
li.textContent = user.name + ' - ' + user.email;
userList.appendChild(li);
});
})
.catch(error => {
console.error('Error fetching data:', error);
});
</script>
</body>
</html>
🔹 data.forEach(...)
We loop through each user object and display their name and email in an unordered list (<ul>).
[
{
"id": 1,
"name": "Leanne Graham",
"email": "[email protected]"
},
{
"id": 2,
"name": "Ervin Howell",
"email": "[email protected]"
}
]
You can access individual fields like:
• user.name
• user.email
✅ Returns promises
It fits well with async/await and modern JavaScript coding styles.
loadUsers();
This version works the same but looks cleaner and is easier to read.
Example Packages:
• express – used to build web servers.
• nodemon – used during development to automatically restart your server when files
change.
✅ Benefits:
• Access to thousands of open-source tools.
• Easily manage project dependencies.
• Keep your code clean and organized.
• Get updates and bug fixes easily.
package.json example:
json
CopyEdit
{
"name": "myapp",
"version": "1.0.0",
"main": "index.js",
"dependencies": {}
}
This file:
• Describes your project.
• Keeps track of installed packages.
• Makes it easy to share your project with others.
2. Installing Packages
To install a package, use:
bash
CopyEdit
npm install package-name
Example:
bash
CopyEdit
npm install express
This:
• Downloads the express package.
Difference:
• dependencies = Needed in production (live project).
• package-lock.json is a file that keeps track of the exact versions of each package and
their sub-packages.
These files help keep the project consistent across different computers.
Step 1: Install
bash
CopyEdit
npm install chalk
Step 2: Use in Code
js
CopyEdit
const chalk = require('chalk');
console.log(chalk.green("This is green text!"));
✅ To remove a package:
bash
CopyEdit
npm uninstall package-name
This will install all the packages listed in the file automatically.
✅ GET Request
✅ POST Request
✅ PUT Request
✅ DELETE Request
Example URL:
/posts/10/comments/5
→ Shows: "Post ID: 10, Comment ID: 5"
URL: /profile/alice
Response: "Welcome to alice's profile"
📂 Common Folder Structure
Here’s what your Express project might look like:
my-app/
├── node_modules/
├── app.js (or server.js)
├── package.json
// Home page
app.get('/', (req, res) => {
res.send('Home Page');
});
// About page
app.get('/about', (req, res) => {
res.send('About Page');
});
app.listen(port, () => {
console.log(`Server is running at http://localhost:${port}`);
});
node app.js
🧼 Good Practices
• Use meaningful names in route paths: /users/:userId is better than /u/:x
• Keep routes organized using separate files (like routes/users.js) as your app grows.
• Use middleware to handle request data, errors, and authentication (optional for now).
javascript
CopyEdit
// Error handling middleware
app.use((err, req, res, next) => {
console.error(err.stack); // Log error in the console
res.status(500).json({ message: 'Something went wrong!', error:
err.message });
});
Or in async functions:
javascript
CopyEdit
app.get('/user', async (req, res, next) => {
try {
// simulate database failure
throw new Error('Database not available');
} catch (err) {
next(err); // pass error to error middleware
}
});
app.use(express.json());
// Example route
app.get('/divide', (req, res, next) => {
try {
const { a, b } = req.query;
if (!b || b == 0) throw new Error('Division by zero not allowed');
// 404 middleware
app.use((req, res, next) => {
res.status(404).json({ message: 'Route not found' });
});
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});
📦 Tools Used
• Node.js – JavaScript runtime
• Express.js – Web framework
• MongoDB Atlas – Free cloud MongoDB database
• Mongoose – MongoDB library for Node.js
📁 Project Setup
🔧 Step 1: Initialize Project
bash
CopyEdit
mkdir express-mongo-app
cd express-mongo-app
npm init -y
npm install express mongoose
// Connect to MongoDB
mongoose.connect('your-mongodb-uri-here', {
useNewUrlParser: true,
useUnifiedTopology: true
}).then(() => console.log('MongoDB Connected'))
.catch(err => console.log(err));
// Start server
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});
🖊 Update User
bash
CopyEdit
PUT /users/<user-id>
{
"name": "Alice Updated"
}
❌ Delete User
bash
CopyEdit
DELETE /users/<user-id>
(i) res.send()
✅ What it does:
• res.send() is used to send a response back to the client.
🧠 Syntax:
javascript
CopyEdit
res.send(body)
📦 Examples:
javascript
CopyEdit
// Send a simple string
res.send('Hello World');
// Send an object
res.send({ name: 'Alice', age: 25 });
When you send an object, res.send() internally converts it to JSON — but for clarity and best
practice, we use res.json() for that (explained below).
🧾 (ii) res.json()
✅ What it does:
• res.json() sends a JSON-formatted response.
• It is the preferred method for APIs.
• Automatically sets the Content-Type: application/json header.
🧠 Syntax:
javascript
CopyEdit
res.json(data)
📦 Examples:
javascript
CopyEdit
// Send a JSON object
res.json({ success: true, message: 'Data received' });
// Send an array
res.json([1, 2, 3]);
• Use res.json() when sending data in JSON format, especially for APIs.
What is Middleware?
🔹 Definition:
Middleware in Express.js is a function that runs between the request and the response. It can:
• Modify the request or response
• End the request-response cycle
• Call the next middleware function
🔹 Example:
javascript
CopyEdit
function logger(req, res, next) {
console.log(`${req.method} ${req.url}`);
next(); // move to the next middleware or route
}
app.use(logger);
🔹 How it Works:
1. User logs in → Server checks credentials
2. If valid → Server sends a signed JWT
3. On future requests, client sends token in the Authorization header
4. Server verifies the token and allows or denies access
🔐 JWT Structure
A JWT has 3 parts (all base64 encoded):
css
CopyEdit
header.payload.signature
Example:
CopyEdit
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJ1c2VySWQiOjEyMywibmFtZSI6IkpvaG4ifQ.
k2uW5bPzi4WqgTqtKmWnPdsTh7YtN2hH5o5NBYUZIiY
// Register Route
app.post('/register', async (req, res) => {
const { username, password } = req.body;
// Hash password
const hashedPassword = await bcrypt.hash(password, 10);
res.send('User registered');
});
// Login Route
app.post('/login', async (req, res) => {
const { username, password } = req.body;
const user = USERS.find(u => u.username === username);
// Protected Route
app.get('/profile', authenticateToken, (req, res) => {
res.send(`Hello ${req.user.username}, this is your profile`);
});
2. Login
bash
CopyEdit
curl -X POST http://localhost:3000/login -H "Content-Type: application/json" -d
'{"username":"john", "password":"1234"}'
🧠 What is async/await?
async/await is a modern way to work with asynchronous code in JavaScript.
It helps write cleaner and more readable code when dealing with asynchronous operations like API
calls, file reading, or database queries.
📦 Tools Required
• Node.js (Install from nodejs.org)
• Express.js (Web framework for Node.js)
• Axios or Fetch (to call external APIs)
• EJS (a simple template engine to render HTML dynamically)
📁 Project Structure
go
CopyEdit
my-app/
├── views/
│ └── users.ejs
├── app.js
├── package.json
Step-by-Step Guide
} catch (error) {
console.error('Error fetching data:', error.message);
res.status(500).send('Error fetching data from API');
}
});
<!DOCTYPE html>
<html>
<head>
<title>User List</title>
</head>
<body>
<h1>List of Users</h1>
<ul>
<% users.forEach(user => { %>
<li><strong><%= user.name %></strong> - <%= user.email %></li>
<% }); %>
</ul>
</body>
</html>
3. Since axios.get() returns a promise, we use await to pause the function until the data
is returned.
4. After data is fetched, we send it to the view (users.ejs) using res.render.
5. In the EJS file, we loop through the array and show user names and emails.
❌ Using .then():
javascript
CopyEdit
axios.get('https://api.com/data')
.then(response => {
// handle data
})
.catch(error => {
// handle error
});
✅ Using async/await:
javascript
CopyEdit
try {
const response = await axios.get('https://api.com/data');
// handle data
} catch (error) {
// handle error
}
Error Handling
Always use try...catch with await to handle errors gracefully. If the API is down or returns
an error, the catch block prevents your app from crashing and shows a meaningful message.
• Start Command:
nginx
CopyEdit
node app.js
• Environment: Node
bash
Copy
Edit
node server.js
Open your browser and go to:
👉 http://localhost:3000