Creating an HTTP Server in NodeJS
Without requiring any other libraries, you may establish HTTP servers using Node.js’s built-in http
module. Node.js is a strong tool for backend web development because of this.
Usually, the http.createServer()
method is used to create a server. This method’s input is a request listener function that runs each time the server receives an HTTP request. Request
(commonly shortened to req
) and response
(often shortened to res
) are two essential objects that are passed to this function.
After creating the server, you need to tell it to listen for incoming connections on a specific port and optionally a hostname using server.listen()
. Node.js servers are long running processes, meaning they’ll keep running until explicitly stopped (e.g., by pressing Ctrl+C
in the terminal) or if they encounter an unhandled error.
HTTP Protocol Basics: The Request/Response Model
The World Wide Web is based on the HyperText Transfer Protocol (HTTP), which uses a simple request/response paradigm. Imagine it like a client placing an order at a counter for food:
- Client (Customer): The person who starts the conversation, be it your web browser, a mobile application, or another server. Usually passive, the client waits to send requests to the server instead of reaching out on its own.
- Request (Order): The server receives a request from the client. A standard HTTP request consists of the following essential components:
- URL (Uniform Resource Locator): Indicates the particular resource the client is requesting (e.g.,
/home
,/api/users
). - HTTP Method (Verb): Indicates the desired action to be performed on the resource. Common methods include:
- GET: To retrieve data from the server. For instance, fetching a list of anime or a webpage.
- POST: To send data to the server. For example, submitting form data.
- PUT: To update an existing resource.
- DELETE: To remove a resource from the server.
- HTTP Headers: Key-value pairs that include extra details about the request, like the
Accept-Encoding
orContent-Type
. - Message Body (Optional): Contains the data being sent with the request; usually used with PUT or POST methods (e.g., JSON payload, form data).
- URL (Uniform Resource Locator): Indicates the particular resource the client is requesting (e.g.,
- Server (Chef): The machine that waits for requests is known as the server (chef).
- Response (Prepared Food): After reviewing the request, the server provides the customer with a response. An HTTP response usually consists of:
- Status Code: A three-digit code that indicates the status of a request (e.g., 200 OK for success, 404 Not Found for a missing resource) is known as the status code.
- HTTP Headers: These include details about the answer, like the data’s
Content-Type
(text/plain
,application/json
,text/html
, etc.). - Message Body (Optional): The actual data being returned, such as an HTML page, JSON object, or plain text, is called the ◦ Message Body (Optional).
The fact that HTTP is stateless that is, each request and answer are autonomous and do not retain any information about prior exchanges should be noted. There is a strong push towards HTTPS (HTTP over TLS/SSL) for safe, encrypted communication, even if HTTP versions like 1.1 are still in use today.
Request () and Response () Objects
You may interact with incoming HTTP requests and create responses primarily using these two objects.
Request Object ()
The incoming client request’s whole contents are contained in the req
object.
req.url
: This field holds the URL path that the client has requested. Using the URL, you can use this to construct routing logic and determine what content to provide.req.method
: The fieldreq.method
specifies the HTTP method (GET, POST, etc.) that was applied to the request.req.headers
: A collection of all the client-sent HTTP headers.- A readable stream is the
req
object itself. You can usedata
events to listen for the data in “chunks” that arrive in response to requests that have a body, such as POST or PUT.
Response Object ()
The HTTP response is created using the res
object and sent back to the client. The stream can be written.
res.writeHead(statusCode, headers)
: When sending a response, the first method you usually call isres.writeHead(statusCode, headers)
. It sets the HTTP response headers (e.g.,Content-Type
) and the HTTP status code (e.g.,200
for OK,404
for Not Found).res.write(data)
: A portion of the response body is sent to the client by theres.write(data)
function. To deliver data progressively, useres.write()
more than once.res.end(data)
: Every response needs to callres.end(data)
to indicate that the response is finished and should be sent to the client by the server. Passing the last piece of data tores.end()
is an optional option.
Here’s an example of a basic Node.js web server handling different routes and content types:
// Import the built-in 'http' module
const http = require('http');
// Define the host and port for the server
const hostname = '127.0.0.1'; // localhost
const port = 3000; // Common port for development
// Create a request listener function
const requestListener = function (req, res) {
// Log the incoming request URL and method for debugging
console.log(`Request received: ${req.method} ${req.url}`);
// Basic routing based on req.url
if (req.url === '/') {
// Handle the root path: send HTML
res.writeHead(200, { 'Content-Type': 'text/html' }); // Set status code and Content-Type header
res.end('<html><body><h1>Welcome to our Node.js Server!</h1><p>Visit /api for JSON data, or /about for plain text.</p></body></html>'); // Send HTML response and close it
} else if (req.url === '/api') {
// Handle '/api' path: send JSON data
res.writeHead(200, { 'Content-Type': 'application/json' }); // Set Content-Type for JSON
const data = { message: 'Hello from Node.js API!', timestamp: new Date().toISOString() };
res.end(JSON.stringify(data)); // Convert JS object to JSON string and send
} else if (req.url === '/about') {
// Handle '/about' path: send plain text
res.writeHead(200, { 'Content-Type': 'text/plain' }); // Set Content-Type for plain text
res.end('This is a simple Node.js web server example. Thanks for visiting!'); // Send plain text
} else {
// Handle any other path: send 404 Not Found
res.writeHead(404, { 'Content-Type': 'text/plain' }); // Set 404 status
res.end('404 Not Found - The page you are looking for does not exist.'); // Send error message
}
};
// Create the server instance using the request listener
const server = http.createServer(requestListener);
// Start the server and listen on the specified port and hostname
server.listen(port, hostname, () => {
console.log(`Server is running on http://${hostname}:${port}`); // Log server startup message
});
To run this code:
- Save it as
server.js
(or any other.js
file). - Open your terminal, navigate to the directory where you saved the file.
- Run the command:
node server.js
.
Example Output in Terminal after running node server.js:
Server is running on http://127.0.0.1:3000
After accessing http://localhost:3000 in a browser:
Request received: GET /
After accessing http://localhost:3000/api in a browser:
Request received: GET /api
After accessing http://localhost:3000/about in a browser:
Request received: GET /about
After accessing http://localhost:3000/nonexistent in a browser:
Request received: GET /nonexistent
You can stop the server by pressing Ctrl+C
in the terminal.
Building a web server in Node.js using the http
module is like setting up a simple post office. The http
module is the building itself, providing the infrastructure. When a client (customer) sends a request (a letter), the server (post office staff) receives it. The req
object is the envelope, containing all the sender’s details, address, and what they’re trying to send.
The res
object is the blank return envelope and paper; you use res.writeHead()
to stamp it with the delivery status and type of content, res.write()
to write the message incrementally, and res.end()
to seal and send it back to the customer. This enables efficient, event-driven communication, allowing the post office to handle many letters without getting stuck waiting for any single one.