CH 5
CH 5
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.
• 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.
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.
• 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
• 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
• Perform Operations: Use the model (User) to interact with the database.
• 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):
mongoose.connect('mongodb://localhost:27017/mywebstore'); // Connect to
MongoDB