Full Stack Unit 1-2
Full Stack Unit 1-2
1.1 INTRODUCTION
Speed and Efficiency: Lightweight and fast, making it ideal for high-
performance applications.
Flexibility: Doesn't enforce a rigid structure, giving developers the
freedom to design their apps as they see fit.
Large Ecosystem: Supported by a vibrant community and an extensive
library of middleware for extending functionality.
Ease of Learning: Simpler than other frameworks, especially for
developers familiar with JavaScript and Node.js.
Basic Example:
// Define a route
app.get('/', (req, res) => {
res.send('Hello, World!');
});
Explanation:
REST emerged as the predominant Web service design model just a couple of
years after its launch, measured by the number of Web services that use it.
Owing to its more straightforward style, it has mostly displaced SOAP and
WSDL-based interface design.
RESTful Architecture:
1. Endpoints
HTTP Method Endpoint Description
GET /users Retrieve all users.
GET /users/{id} Retrieve a specific user.
POST /users Create a new user.
PUT /users/{id} Update a specific user.
DELETE /users/{id} Delete a specific user.
2. Example Interaction
GET Request:
GET /users/123
Response:
{
"id": 123,
"name": "John Doe",
"email": "[email protected]"
}
POST Request:
POST /users
Content-Type: application/json
{
"name": "Jane Doe",
"email": "[email protected]"
}
{
"id": 124,
"name": "Jane Doe",
"email": "[email protected]"
}
// GET /resource/123
// Returns the state of the resource with ID 123
app.get('/resource/:id', function(req, res) {
var id = req.params.id;
var resource = findResourceById(id);
res.json(resource);
});
// POST /resource
// Creates a new resource with the state specified in the request body
app.post('/resource', function(req, res) {
var resource = req.body;
var id = createResource(resource);
res.json({ id: id });
});
// PUT /resource/123
// Updates the state of the resource with ID 123 with the state specified in
the request body
app.put('/resource/:id', function(req, res) {
var id = req.params.id;
var resource = req.body;
updateResource(id, resource);
res.sendStatus(200);
});
// DELETE /resource/123
// Deletes the resource with ID 123
app.delete('/resource/:id', function(req, res) {
var id = req.params.id;
deleteResource(id);
res.sendStatus(200);
});
What is Express.js?
Frontend: The user interface that interacts with the user (HTML, CSS,
JavaScript, frameworks like React, Angular, or Vue.js).
Backend: Handles data processing, server logic, and APIs (e.g.,
Express.js with Node.js).
Database: Stores application data (e.g., MongoDB, MySQL, or
Firebase).
1. Frontend:
o HTML: Structure of the web page.
o CSS: Styling and layout.
o JavaScript: Interactivity and dynamic content.
o Frontend Frameworks/Libraries: React, Angular, or Vue.js.
2. Backend:
o Node.js: JavaScript runtime for building server-side applications.
o Express.js: Framework for creating web servers and APIs.
3. Database:
o MongoDB (NoSQL) or PostgreSQL/MySQL (SQL) for storing
and managing data.
4. Version Control:
o Git: To manage code versions.
o GitHub/GitLab: For collaboration and deployment.
5. Tools:
o Postman/Thunder Client: For API testing.
o VS Code: Popular code editor.
6. Deployment Platforms:
o Heroku, Vercel, AWS, or DigitalOcean for hosting applications.
1. Frontend Development:
o Create a user interface using HTML, CSS, and JavaScript.
o Use a framework (React, Vue.js) for component-based
architecture.
2. Backend Development:
o Use Express.js to set up a server.
o Define API routes to handle HTTP requests (GET, POST, PUT,
DELETE).
app.use(express.json());
3. Database Integration:
o Connect Express to a database (e.g., MongoDB with Mongoose).
o Example of connecting to MongoDB:
o const mongoose = require('mongoose');
o
omongoose.connect('mongodb://localhost:27017/mydatabase', {
o useNewUrlParser: true,
o useUnifiedTopology: true,
o }).then(() => {
o console.log('Connected to MongoDB!');
o }).catch(err => console.error('MongoDB connection error:', err));
4. Frontend-Backend Communication:
o Use fetch or Axios in the frontend to make API calls to the
backend.
Example in React:
fetch('/api')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
5. Deployment:
o Bundle the frontend and backend code.
o Deploy to a cloud provider like Heroku or AWS.
Conclusion
uilding your first web server is an exciting way to dive into web development.
Here's a simple guide to help you set up a basic web server. For simplicity, we'll
use Node.js and its built-in HTTP module, as it provides an easy way to get
started.
Prerequisites
1. Install Node.js: Download and install Node.js. This will give you access
to both node and npm (Node Package Manager).
2. Code Editor: Use an editor like VS Code
cd my-web-server
res.setHeader('Content-Type', 'text/html');
res.end('<h1>Hello, World!</h1>');
});
});
5. Run Your Server: In your terminal, run
node server.js
Server running at http://127.0.0.1:3000/
6. Access the Server: Open your browser and go to
http://127.0.0.1:3000/.
You should see "Hello, World!" displayed
Using Built-in HTTP module
HTTP and HTTPS, these two inbuilt modules are used to create a
simple server. The HTTPS module provides the feature of the
encryption of communication with the help of the secure layer feature
of this module. Whereas the HTTP module doesn’t provide the
encryption of the data.
Approach
Building a simple Node.js web server with the http module by using
http.createServer(), which listens for requests, sends responses, and is
ideal for understanding core server functionality.
Project structure: It will look like this.
// Filename - index.js
// Creating server
const server = http.createServer((req, res) => {
// Sending the response
res.write("This is the response from the server")
res.end();
})
utput: Now open your browser and go to http://localhost:3000/, you will see
the following output:
The express.js is one of the most powerful frameworks of the node.js that works
on the upper layer of the http module. The main advantage of using express.js
server is filtering the incoming requests by clients.
Approach
To create a web server with Express initialize an app with express(), defining
routes with app.get(), and sending responses using res.send(). Express simplifies
development with built-in features and middleware.
Installing module: Install the required module using the following command.
// Filename - index.js
})
})
// Server setup
app.listen(3000, () => {
console.log("Server is Running")
})
node index.js
Output: Now open your browser and go to http://localhost:3000/, you will see the
following output:
1.5 NODEMON
Although you can clone nodemon from Git but the above is a better
recommendation. The above command will install the nodemon
globally into your system. Also, you can install further dependencies
which are highly recommended for a smooth workflow using the below
command.
To create your node project, all you need to do is to follow the below
very crucial steps.
1. npm init -y
Now, all you have to do is to install express using the below command
whether you have yarn or node installed in your system.
r
npm install express --save
The next step is to add some plain Javascript and to do that you need to
use this Javascript to configure the express through node for making
the port connected to the server so that results are displayed on the
console. Use the below sample code to configure your server with a
listener port.
// server.js file
res.status(300).send('Hello JavaTpoint!');
});
app.listen(8080);
In the above code, we have established our port to listen to port number
8080. The res and req are defined as the response and the request that
would be listened through the port.
The next step is to start the server using the below command.
nodemon server
Conversely, nodemon will search for files driven out by your project
and will look for a primary package.json file to start the script. Also,
you can either opt for launching nodemon directly for your application
by writing the start script in the package.json file. The package.json file
may have some dependencies as shown below.
"name": "nodemon-exp",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.16.3"
}
Now, all you need to do is to hit the command as shown below.
npm start
1. -exec
This option is used primarily to specify the binary executable objects
with the associated files. For instance, while combining the TypeScript
files, it will run binary execution methods to reflect changes in the
dependencies.
1. --ignore
1. -ext
This option is used to notify the watchable file extensions. For this, you
need to specify it comma separation like --ext js, ts.
1. --delay
1. --watch
This option is used to objectify multiple directories associated with
watch. Using this option will let you specifically watch the
subdirectories or files constituting your project's data.
1. --verbose
This option is primarily used to display the changes that have been
made while starting the nodemon server.
Nodemon is a utility that helps develop Node.js-based applications by
automatically restarting the application when file changes in the
directory are detected. It is particularly useful during development to
streamline the workflow and avoid manual restarts of the server after
each change.
Key Features
Automatically restarts the Node.js application when changes are
detected.
Configurable to watch specific files, extensions, or directories.
Supports custom scripts and events.
Can be used globally or as a project dependency.
Installation
Install Globally:
Usage
nodemon app.js
nodemon server.js
Configuration
You can create a nodemon.json file in the root of your project for
custom configurations:
"watch": ["src"],
"ext": "js,json",
"ignore": ["node_modules/*"],
Common Commands
Restart manually: Type rs in the terminal where nodemon is
running.
Ignore certain files or directories:
nodemon --ignore logs/*
Run with a specific delay:
nodemon --delay 2
.env file:
DB_HOST=localhost
DB_PORT=5432
API_KEY=your_api_key_here
2. In React (Frontend):
REACT_APP_API_URL=https://api.example.com
REACT_APP_ENV=production
3. In Deployment:
4. In Docker:
When using Docker, you can pass environment variables through the
docker-compose.yml file or directly in the Dockerfile.
environment:
- DB_HOST=localhost
- DB_PORT=5432
Best Practices:
1. Never commit .env files: Ensure .env files are listed in .gitignore to
prevent them from being pushed to version control systems.
2. Use default values: Provide fallback values for development
environments, or use default values directly in the code if the
environment variable is not set.
3. Use different configurations for each environment: Create multiple
.env files like .env.dev, .env.prod for different environments.
4. Secure storage in production: For production, store environmental
variables securely (e.g., via environment management in cloud services or
using secret management tools like AWS Secrets Manager).
Router parameters are dynamic values that are used to pass information through
URLs, typically in web applications. They are commonly used in frameworks
like Express (Node.js), React Router (for client-side routing), and others.
1. Route Parameters (Path Parameters): These are part of the URL path
and are typically represented by a colon (:) followed by a variable name.
For example:
o In Express (Node.js):
o app.get('/user/:id', (req, res) => {
o const userId = req.params.id;
o res.send(`User ID is ${userId}`);
o });
o In React Router:
o <Route path="/user/:id" component={User} />
Here, :id is a route parameter that can be accessed in your route handler.
2. Query Parameters: These are passed in the URL after a ? symbol and
typically come in key-value pairs, like ?key=value. They are often used
for filtering or pagination. For example:
o In Express:
o app.get('/search', (req, res) => {
o const query = req.query.q; // Retrieves value of 'q'
o res.send(`Searching for: ${query}`);
o });
o In React Router:
o // The query string could look like /search?q=example
o const queryParams = new URLSearchParams(location.search);
o const query = queryParams.get('q');
Both types allow developers to manage dynamic content and handle user input
more efficiently in their web applications.
GET requests are commonly used for retrieving data from a server. In
Express.js, you can handle GET requests using the app.get() method. Here's an
example:
const users = [
];
res.json(users);
});
In this example, when a GET request is made to ‘/api/users’, the server responds
with JSON data containing a list of users.
1. Define a route that maps to the URL where the request is made.
2. Specify the HTTP method (GET in this case).
3. Return the desired response when the route is accessed.
Handling an HTTP POST request involves setting up a server that can receive,
process, and respond to requests made by clients (like web browsers,
applications, or other servers). Here’s a simple breakdown of how to handle an
HTTP POST request:
Basic Steps:
1. Set Up a Server: You need a web server or framework that listens for
HTTP requests. In many programming languages, libraries or frameworks
can make this process easier. For example, in Python, Flask or Django
can be used; in Node.js, Express is commonly used.
2. Configure the Endpoint: You need to define an endpoint in your server
that will handle the POST request. A POST request typically sends data
to the server (e.g., form data, JSON, etc.).
3. Extract the Data: POST requests usually include data in the request
body (such as form data or JSON). You'll need to extract and process this
data.
4. Respond to the Request: After processing the POST request, you send a
response back to the client, often with some kind of status message or
result of the request.
app = Flask(__name__)
@app.route('/submit', methods=['POST'])
def handle_post_request():
data = request.get_json()
if __name__ == '__main__':
app.run(debug=True)
Explanation:
});
app.listen(3000, () => {
});
Explanation:
def handle_post_request():
name = request.form['name']
email = request.form['email']
});
This gives a basic overview of handling POST requests. Depending on your use
case, you can customize this to handle authentication, validate data, or save to a
database.
1. What is Postman?
Postman is a popular API testing tool that allows you to send HTTP requests to
interact with APIs. It simplifies testing RESTful APIs by providing a user-
friendly interface and various features for request creation, testing, and
automation.
2. Setting Up Postman
Open Postman.
Click the New button on the left sidebar.
Choose Request from the available options.
In the Request window, select the HTTP method you want to use (GET,
POST, PUT, DELETE, PATCH, etc.) from the dropdown next to the
URL bar.
o GET: Retrieve data.
o POST: Send data to the server.
o PUT: Update data on the server.
o DELETE: Remove data from the server.
In the URL field, enter the API endpoint URL you want to call. For
example, https://api.example.com/v1/resource.
"username": "john_doe",
"password": "12345"
After entering the necessary information, click the Send button to send
the request to the API.
Once the request is sent, Postman will show the response in the bottom
section.
o Status: The HTTP status code (e.g., 200 OK, 404 Not Found).
o Body: The response body, often in JSON or XML format.
o Headers: The headers returned by the server.
a. Environment Variables
Create a new environment via the gear icon in the top-right corner.
Add variables like {{base_url}} and use them in requests, e.g.,
{{base_url}}/v1/resource.
b. Authentication
Bearer Token: If the API requires authentication via a token, you can
enter it under the Authorization tab in Postman.
o Select Bearer Token from the dropdown and paste your token in
the text field.
Basic Authentication: For username and password authentication, use
Basic Auth under the Authorization tab.
c. Pre-request Scripts
You can write JavaScript code under the Pre-request Script tab that will
execute before the request is sent. This can be useful for setting dynamic
variables.
d. Tests
You can write tests to validate the response of the API call.
e. Collection Runner
You can run a collection of API requests in sequence, passing data from one
request to another (via environment variables or data files). This is useful for
testing multiple endpoints in an automated way.
You can save and export your requests by clicking the Save button.
Share collections by exporting them to a file and sharing them with
teammates.
7. Automating Requests
Postman provides tools for automating API requests and running tests
using Newman, the Postman CLI tool. This allows you to execute your
Postman collections via the command line or integrate them into CI/CD
pipelines.
8. Best Practices
Use Variables: To keep your tests flexible and reusable, use environment
or collection variables.
Test with Real Data: Always use realistic test data and handle edge
cases.
Write Tests: Ensure your API responses match expectations by writing
automated tests in Postman.
Conclusion
Postman is a versatile tool for making API requests and testing responses. By
leveraging its various features like environments, authentication, and automated
testing, you can streamline your API development and testing processes.
Definition: Input validation refers to the process of ensuring that the data
provided to a program or system is both correct and secure. This step is
essential in preventing unexpected behaviors, errors, and vulnerabilities in an
application. Proper input validation protects against malformed data, attacks
like SQL injection, and ensures data integrity.
1. Client-Side Validation:
o Performed in the user's browser, before the data is sent to the
server.
o It provides immediate feedback to the user but can be bypassed by
malicious users.
o Often implemented using JavaScript or HTML5 validation
attributes.
o Example: Checking if an email address is in the correct format
before submitting a form.
2. Server-Side Validation:
o Performed on the server after the data has been received from the
client.
o More secure than client-side validation as it cannot be bypassed by
altering the client-side code.
o Example: Ensuring that a user's password is of an acceptable length
and complexity.
3. Database-Level Validation:
o Enforced within the database itself, such as through constraints,
triggers, or stored procedures.
o Ensures data integrity and accuracy directly at the data storage
level.
1. Whitelisting (Allow-listing):
o Accept only data that matches a predefined set of criteria or
patterns.
o Recommended approach as it minimizes the risk of unexpected
data being processed.
o Example: If accepting an email address, ensure the string matches
the pattern [email protected] (using regular expressions).
2. Blacklisting (Deny-listing):
o Reject data that matches known bad patterns or values.
o Not as secure as whitelisting, since new or unknown malicious
inputs may not be detected.
o Example: Rejecting inputs that contain SQL keywords (like DROP,
DELETE).
3. Length Validation:
o Check that the input is neither too short nor too long for the
expected format.
o Prevents buffer overflows and ensures the data fits within the
expected size for efficient processing.
o Example: Username should be at least 5 characters and no more
than 20.
4. Type Validation:
o Ensure the input matches the expected data type.
o Example: If a field expects an integer, input validation checks if
the value is an integer (not a string or float).
5. Format Validation:
o Checks whether the input conforms to a specific pattern or format,
such as email, date, phone number, etc.
o Example: Ensuring a phone number is in the format (XXX) XXX-
XXXX.
6. Range Validation:
o For numerical or date values, validate that they fall within a
permissible range.
o Example: Age must be between 18 and 120 years.
7. Cross-Site Scripting (XSS) Prevention:
o Validate user inputs to prevent malicious scripts from being
executed on the client side.
o Often achieved by sanitizing input, stripping or encoding harmful
characters like <, >, and &.
8. SQL Injection Prevention:
o Ensure that inputs do not contain SQL commands or special
characters that can manipulate SQL queries.
o Example: Using prepared statements with parameterized queries
instead of directly concatenating inputs into SQL queries.
9. Escape Special Characters:
o Escape characters that have special meanings in certain contexts,
like HTML, JavaScript, or SQL.
o Example: Replacing & with & in HTML to prevent XSS.
Conclusion:
To handle an HTTP PUT request, you typically need to set up a route in your
web framework that listens for PUT requests at a specific endpoint. This request
method is generally used to update an existing resource on the server. Here's a
basic example of how to handle a PUT request in a few popular web
frameworks.
Express (Node.js)
const updatedData = req.body; // Get the updated data from the request body
// You would typically find the resource by its ID and update it in the
database
});
app.listen(3000, () => {
});
Flask (Python)
app = Flask(__name__)
@app.route('/update-resource/<int:id>', methods=['PUT'])
def update_resource(id):
updated_data = request.json # Get the updated data from the request body
# You would typically find the resource by its ID and update it in the
database
if __name__ == '__main__':
app.run(debug=True)
Django (Python)
import json
@csrf_exempt # Disable CSRF for this example, you should handle CSRF in
production
if request.method == 'PUT':
# Typically, you would query your database and update the record here
# path('update-resource/<int:id>/', views.update_resource),
ASP.NET (C#)
using Microsoft.AspNetCore.Mvc;
[Route("api/[controller]")]
[ApiController]
[HttpPut("{id}")]
{
// Simulate updating a resource
// Typically, you would find the resource by its ID and update it in your
database
1. Node.js (Express.js)
});
app.listen(3000, () => {
});
In this example:
2. Python (Flask)
app = Flask(__name__)
@app.route('/resource/<int:id>', methods=['DELETE'])
def delete_resource(id):
# Logic to delete the resource by its ID
if __name__ == '__main__':
app.run(debug=True)
Here:
In Spring Boot, you can handle DELETE requests with a method in a controller:
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
@DeleteMapping("/resource/{id}")
This example:
4. PHP
In PHP, you would handle the DELETE request manually, often using a router
or framework. Here's a simple example:
<?php
if ($_SERVER['REQUEST_METHOD'] == 'DELETE') {
?>
1. Define the Route: Ensure you have a route that responds to the HTTP
DELETE method.
2. Extract Data: Extract any necessary data (like resource ID) from the
request path, query, or body.
3. Delete Resource: Perform the logic required to delete the resource from
the database or storage.
4. Respond: Send an appropriate response back to the client, typically with
a status code (e.g., 200 OK for success or 404 if the resource is not
found).
These are basic examples, and in production environments, you would add more
features like authentication, validation, and error handling to ensure your
DELETE requests are secure and robust.