0% found this document useful (0 votes)
2 views8 pages

CH 5

Node.js is an open-source JavaScript runtime environment that enables the execution of JavaScript code outside of a browser, primarily used for building scalable network applications and APIs. It operates on a single-threaded event loop with non-blocking I/O, allowing it to handle multiple connections efficiently. The document also covers installation, web server creation, event handling, CRUD operations, and connecting to NoSQL databases like MongoDB using Mongoose.

Uploaded by

cahon43167
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views8 pages

CH 5

Node.js is an open-source JavaScript runtime environment that enables the execution of JavaScript code outside of a browser, primarily used for building scalable network applications and APIs. It operates on a single-threaded event loop with non-blocking I/O, allowing it to handle multiple connections efficiently. The document also covers installation, web server creation, event handling, CRUD operations, and connecting to NoSQL databases like MongoDB using Mongoose.

Uploaded by

cahon43167
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 8

Got it! Let's cover Unit 5: Introduction to Server-side JS Framework – Node.

js, keeping the


explanations concise and to the point for your oral exam.

Unit 5: Introduction to Server-side JS Framework – Node.js (05) - Concise


Overview
Node.js is an open-source, cross-platform JavaScript runtime environment that allows you to
execute JavaScript code outside a web browser. It's primarily used for building fast, scalable
network applications, often real-time applications and APIs.

1. Introduction - What is Node.js


• What it is: Node.js is not a programming language (it uses JavaScript), and it's not a web
server (it can create web servers). It's a runtime environment that runs JavaScript code.
• Powered by V8 Engine: It uses Google Chrome's V8 JavaScript engine, which is very fast
at executing JavaScript code.
• Event-Driven, Non-blocking I/O: Node.js is designed for building highly scalable
applications by using an event-driven, non-blocking (asynchronous) I/O model. This means
it can handle many concurrent connections efficiently without creating a new thread for each
connection.
• Server-Side JavaScript: It allows developers to use JavaScript for both frontend (React,
etc.) and backend development, enabling full-stack JavaScript.

2. Architecture
• Single-Threaded Event Loop: Node.js operates on a single-threaded event loop. This is a
core concept that allows it to handle concurrency effectively.
• When an asynchronous operation (like reading a file, making a database query, or
handling an HTTP request) is initiated, Node.js offloads it to the operating system or
an internal thread pool.
• Instead of waiting, the single thread continues processing other requests.
• When the asynchronous operation completes, a callback function is placed in an
event queue.
• The Event Loop constantly checks this queue and pushes callbacks to the call stack
when the main thread is free.
• Non-Blocking I/O (Asynchronous): All I/O operations in Node.js are non-blocking. This
means that a request to read a file or query a database doesn't halt the execution of other
code; instead, a callback function is registered to be executed once the operation finishes.
• V8 Engine: Efficiently executes JavaScript code.
• Node.js API/Bindings: Provides access to low-level system functionalities (file system,
networking).
3. Features of Node.js
• Asynchronous and Event-Driven: Core design for high concurrency and responsiveness.
• Single-Threaded: Leverages the event loop, not traditional multi-threading.
• Fast Code Execution: Thanks to Google's V8 JavaScript Engine.
• Non-blocking I/O: Handles I/O operations without blocking the main thread.
• Highly Scalable: Can handle a large number of concurrent connections.
• NPM (Node Package Manager): The largest ecosystem of open-source libraries in the
world, making it easy to add functionalities to Node.js applications.
• Cross-Platform: Runs on Windows, macOS, and Linux.
• No Buffering: Streams data in chunks, avoiding large memory footprints.

4. Installation and Setup


1. Download: Download the official installer from the Node.js website (nodejs.org). It
includes Node.js runtime and npm.
2. Installation: Run the installer and follow the prompts.
3. Verification:
• Open your terminal/command prompt.
• Check Node.js version: node -v
• Check npm version: npm -v
4. Project Setup:
• Create a new directory for your project.
• Navigate into it: cd my-nodejs-app.
• Initialize a new Node.js project: npm init -y (creates package.json).
• Install necessary packages: npm install express mongoose (example).

5. Creating Web Servers with HTTP (Request & Response)


Node.js has a built-in http module to create web servers.

• http.createServer(): Creates an HTTP server instance.

• Callback Function: Takes a callback function that is executed for every incoming HTTP
request. This function receives two arguments:
• request (or req): An http.IncomingMessage object containing information
about the incoming request (URL, headers, method, query parameters, body).
• response (or res): An http.ServerResponse object used to send data back
to the client (status codes, headers, response body).
• listen() method: Starts the server and listens for requests on a specified port.

• Example (Basic HTTP Server):


JavaScript
const http = require('http');

const server = http.createServer((req, res) => {


// Set HTTP header
res.writeHead(200, { 'Content-Type': 'text/plain' });

// Send the response body


res.end('Hello from Node.js Server!\n');
});

const port = 3000;


server.listen(port, () => {
console.log(`Server running at http://localhost:${port}/`);
});

• Request & Response Objects:


• req.url: The requested URL path (e.g., /users, /products?id=1).
• req.method: The HTTP method (e.g., GET, POST).
• res.writeHead(statusCode, headers): Sets the HTTP status code and
response headers.
• res.end(data): Sends the response body and signals that the response is
complete.

6. Event Handling
Node.js heavily relies on the event-driven architecture. Many core Node.js modules (like http,
fs, net) are built using the EventEmitter class.

• EventEmitter: A class that allows you to emit named events that cause corresponding
functions ("listeners") to be called.
• on(eventName, listener): Registers a listener for an event.
• emit(eventName, [arg1], [arg2], ...): Triggers an event.
• HTTP Server Events: The http.Server instance itself is an EventEmitter.

• server.on('request', (req, res) => { ... }): This is the most


common event, handling incoming HTTP requests.
• server.on('listening', () => { ... }): Fired when the server starts
listening.
• server.on('error', (err) => { ... }): Fired if an error occurs.
• Example (Custom Event):
JavaScript
const EventEmitter = require('events');
const myEmitter = new EventEmitter();

myEmitter.on('greet', (name) => {


console.log(`Hello, ${name}!`);
});

myEmitter.emit('greet', 'Alice'); // Output: Hello, Alice!


7. GET & POST Implementation
Implementing GET and POST with the raw http module often involves checking req.method
and parsing req.url. For POST requests, you also need to handle the incoming request body.

• GET Implementation:
• Check req.method === 'GET'.
• Parse req.url to extract path and query parameters (e.g., using url.parse()
from the url module or new URL(req.url, base)).
• Send appropriate response.
• POST Implementation:
• Check req.method === 'POST'.
• Collecting Request Body: The request body for POST (and PUT/PATCH) requests
arrives in chunks. You need to listen for data events to collect these chunks and the
end event to process the complete body.
• req.on('data', chunk => { body += chunk; });
• req.on('end', () => { // body is complete, parse it
(e.g., JSON.parse(body)) });
• Send appropriate response.
• Example (Conceptual http server for GET/POST):

JavaScript
const http = require('http');
const url = require('url'); // For parsing URLs

const server = http.createServer((req, res) => {


const parsedUrl = url.parse(req.url, true); // true to parse query
string
const path = parsedUrl.pathname;
const query = parsedUrl.query;

if (req.method === 'GET' && path === '/api/data') {


res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ message: 'GET request received', params:
query }));
} else if (req.method === 'POST' && path === '/api/submit') {
let body = '';
req.on('data', chunk => {
body += chunk.toString(); // convert Buffer to string
});
req.on('end', () => {
try {
const data = JSON.parse(body);
res.writeHead(200, { 'Content-Type':
'application/json' });
res.end(JSON.stringify({ status: 'success', receivedData:
data }));
} catch (e) {
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.end('Invalid JSON in request body');
}
});
} else {
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.end('Not Found');
}
});

server.listen(3000, () => console.log('Server running on port 3000'));

• Express.js: For real-world applications, frameworks like Express.js are used. They abstract
away the raw HTTP module complexities, making routing, middleware, and
request/response handling much simpler.
JavaScript
// With Express (much simpler)
const express = require('express');
const app = express();
app.use(express.json()); // Middleware to parse JSON request bodies

app.get('/api/data', (req, res) => {


res.json({ message: 'GET request received', params: req.query });
});

app.post('/api/submit', (req, res) => {


res.json({ status: 'success', receivedData: req.body });
});

app.listen(3000, () => console.log('Express Server running on port


3000'));

8. Connect to NoSQL Database using Node.js


Node.js applications commonly connect to NoSQL databases for their flexibility and scalability,
especially with JSON data.
• Popular NoSQL Databases:
• MongoDB: A popular document-oriented database.
• Cassandra, CouchDB, Redis etc.
• Drivers/ODMs: Node.js uses specific client libraries or Object Data Mappers (ODMs) to
interact with these databases.
• For MongoDB, the most common ODM is Mongoose.
• Mongoose provides schema-based modeling, allowing you to define the
structure of your data within MongoDB.
• It simplifies interaction with MongoDB (connections, CRUD operations).
• Steps to Connect (using Mongoose for MongoDB):
• Install Mongoose: npm install mongoose
• Import: const mongoose = require('mongoose');
• Connect:
mongoose.connect('mongodb://localhost:27017/mydb');
• Define Schema: (Optional but recommended for structure)
JavaScript
const userSchema = new mongoose.Schema({
name: String,
email: String
});
const User = mongoose.model('User', userSchema);

• Perform Operations: Use the model (User) to interact with the database.

9. Implementation of CRUD Operations


CRUD (Create, Read, Update, Delete) are the four basic functions of persistent storage. In a Node.js
application (often with Express.js and a database like MongoDB/Mongoose), these map directly to
HTTP methods.
• 1. CREATE (HTTP POST):

• Client sends a POST request to a collection URI (e.g., /api/users) with the new
resource data in the request body (JSON).
• Node.js server (e.g., Express route) receives the data.
• Server uses the database driver/ODM (User.create(req.body)) to insert a
new document into the database.
• Server responds with 201 Created status and the newly created resource.
• 2. READ (HTTP GET):

• Read All: Client sends GET request to a collection URI (e.g., /api/users).
• Server queries the database to find all documents (User.find({})).
• Server responds with 200 OK and an array of resources.
• Read One: Client sends GET request to a specific resource URI (e.g.,
/api/users/123).
• Server queries the database for the document by ID
(User.findById(req.params.id)).
• Server responds with 200 OK and the single resource, or 404 Not
Found.
• 3. UPDATE (HTTP PUT or PATCH):

• Client sends PUT (full replacement) or PATCH (partial update) request to a specific
resource URI (e.g., /api/users/123) with updated data in the body.
• Server uses the database driver/ODM to update the document
(User.findByIdAndUpdate(req.params.id, req.body, { new:
true })). {new: true} returns the updated document.
• Server responds with 200 OK and the updated resource, or 404 Not Found.
• 4. DELETE (HTTP DELETE):

• Client sends a DELETE request to a specific resource URI (e.g.,


/api/users/123).
• Server uses the database driver/ODM to delete the document
(User.findByIdAndDelete(req.params.id)).
• Server responds with 204 No Content (if successful) or 404 Not Found.
• Example (Conceptual CRUD with Express & Mongoose):
JavaScript
const express = require('express');
const mongoose = require('mongoose');
const app = express();
app.use(express.json()); // Enable JSON body parsing

mongoose.connect('mongodb://localhost:27017/mywebstore'); // Connect to
MongoDB

const productSchema = new mongoose.Schema({ name: String, price:


Number });
const Product = mongoose.model('Product', productSchema);

// CREATE - POST /products


app.post('/products', async (req, res) => {
try {
const newProduct = await Product.create(req.body);
res.status(201).json(newProduct);
} catch (error) { res.status(400).json({ error: error.message }); }
});

// READ All - GET /products


app.get('/products', async (req, res) => {
const products = await Product.find({});
res.status(200).json(products);
});

// READ One - GET /products/:id


app.get('/products/:id', async (req, res) => {
const product = await Product.findById(req.params.id);
if (!product) return res.status(404).json({ message: 'Product not
found' });
res.status(200).json(product);
});

// UPDATE - PUT/PATCH /products/:id


app.put('/products/:id', async (req, res) => {
const updatedProduct = await Product.findByIdAndUpdate(req.params.id,
req.body, { new: true });
if (!updatedProduct) return res.status(404).json({ message: 'Product
not found' });
res.status(200).json(updatedProduct);
});

// DELETE - DELETE /products/:id


app.delete('/products/:id', async (req, res) => {
const deletedProduct = await Product.findByIdAndDelete(req.params.id);
if (!deletedProduct) return res.status(404).json({ message: 'Product
not found' });
res.status(204).send(); // 204 No Content for successful deletion
});

app.listen(3000, () => console.log('Node.js API Server running on port


3000'));

Concise Practice Questions (Unit 5: Node.js)


1. What is Node.js, and how does its use of the V8 engine benefit its performance?
2. Explain the core concept of Node.js's "single-threaded event loop" and "non-blocking I/O."
How do these contribute to its scalability?
3. You're creating a basic web server in Node.js. What built-in module would you use, and
what are the two main objects (req, res) passed to its request handling callback?
4. How does Node.js's event-driven nature manifest in its core modules? Give an example of
an event listener you might set up on an HTTP server.
5. Describe the key difference in handling a GET request versus a POST request when building
a server with Node.js's native http module.
6. When implementing CRUD operations for a RESTful API using Node.js, which HTTP
method typically maps to "Create," "Read," "Update," and "Delete" actions respectively?
7. Why is a library like Mongoose commonly used when connecting a Node.js application to a
MongoDB database?
8. What is the purpose of npm in the Node.js ecosystem?

You might also like