Decoding Node JS: Understand the internal working of Node JS server
Disclaimer: “Node js and libuv are the onion layers, the more you will peel it, the more you will cry”
What is Node JS?
Node.js is an open-source runtime environment built on Chrome’s V8 engine by Ryan Dahl in 2009. It enables programmers to write JavaScript on both the client-side and server-side. Traditionally, JavaScript lacked the capability to control the network or filesystem directly, but Node.js fills this gap. The ‘http’ module in Node.js provides the necessary functionality to manage network operations.
One of the key features of Node.js is its event-driven, non-blocking I/O model, which makes it lightweight and efficient, especially for I/O-heavy tasks like web servers.
Understanding the HTTP Interface
The HTTP interface in Node.js is designed to support the features of the protocol, which have traditionally been difficult to use. A server, in simple terms, is just another computer that is up and running all the time, listening to requests made by a user and serving the user with some response, thereby creating a request-response cycle.
Creating a Server
Let’s Understand the inner working of a node server using the code below:
const http = require('http');
const server=http.createServer((req,res)=>{
res.statusCode=200
res.end('bye'); // marks the end of stream send by server
// to the user making the request.
})
const PORT=4000;
server.listen(PORT,()=>{
console.log(`Listening On Port ${PORT}`)
});
Role Of Libuv in Node JS
When a request comes to a server (say on Port 80), Node.js, being written in JavaScript, cannot directly control the network. This is where libuv comes into the picture. Libuv is a multi-platform support library mainly written in C and C++, and it acts as an interface between the computer and Node.js. It helps Node.js interact with the computer and manage network operations.
Libuv is responsible for managing the event loop, which is the backbone of Node.js's non-blocking I/O operations. It handles asynchronous I/O operations, such as file system access, network communication, and timers, allowing Node.js to perform these tasks efficiently without blocking the execution of other code.
Whenever a request comes to a server, it’s not in text format; rather, it comes in the form of streams of data or bytes of data. To convert these streams or bytes into a string format, we use the ‘http’ module of Node.js.
Understanding the Request-Response Cycle
Whenever a request comes to a server, libuv handles it by managing two key processes: the incoming section (the request, or req
in the code or Box 1) and the outgoing section (the response, or res
in the code or Box 2). The request and response are essentially JavaScript objects.
Request Object (
req
): This is an instance ofIncomingMessage
that primarily contains properties describing the incoming request, such as the URL, headers, and method.Response Object (
res
): This object contains methods that you can use to send data back to the client. One of the most commonly used methods is.end()
, which marks the end of the request-response stream cycle.
When a user makes a request to a specific route like /database
or /profile
, an event is emitted within the Node.js environment. Libuv plays a crucial role in this process, but it doesn't handle routing directly. Instead, it processes the I/O events and triggers the appropriate callbacks within Node.js.
Node.js, using the http
module or a framework like Express, checks the route being requested and executes the corresponding function. This function processes the request and generates a response, which is then passed back to libuv. Libuv then transmits the response back to the user, completing the request-response cycle.
Conclusion
This is a brief overview of how a Node.js server works internally. By understanding the interaction between Node.js, libuv, and the HTTP module, you can better grasp the underlying mechanics of server-side JavaScript.
Connect with me for more such blogs. Happy coding! :)
Subscribe to my newsletter
Read articles from Koustav Chatterjee directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Koustav Chatterjee
Koustav Chatterjee
I am a developer from India with a passion for exploring tech, and have a keen interest on reading books.