Why We use Express as http server

Node comes with a built in module called http to create web servers. consider following code

const http = require('http');

// Create the server
const server = http.createServer((req, res) => {
  // Set response header for CORS and content type
  res.setHeader('Content-Type', 'text/plain');
  
  // Handle requests based on URL and method
  if (req.method === 'GET' && req.url === '/') {
    res.writeHead(200);
    res.end('Welcome to the Home Page');
  } else if (req.method === 'GET' && req.url === '/about') {
    res.writeHead(200);
    res.end('About Page');
  } else {
    res.writeHead(404);
    res.end('Page Not Found');
  }
});

// Server listens on port 3000
server.listen(3000, () => {
  console.log('Server is running on http://localhost:3000');
});

Explanation of the Example Code

  • Import http Module: const http = require('http'); imports the http module.
  • Create Server: http.createServer() creates the server, which receives (req, res) as arguments.
  • Set Response Header: Setting the Content-Type header to text/plain so that the browser knows it’s receiving plain text.
  • Routing Logic:
    • If the request method is GET and the URL is /, it sends a “Welcome to the Home Page” response.
    • If the request method is GET and the URL is /about, it sends an “About Page” response.
    • For all other URLs, it sends a 404 “Page Not Found” response.
  • Start the Server: server.listen(3000, ...); starts the server, making it listen on port 3000.

Running the server

Save the code in a file, say server.js. Run it using the command

node server.js

http://localhost:3000/ should return “Welcome to the Home Page”.

Poblem with this approach

Coding like above is a real pain as the code gets messy as soon as our application starts expanding

Express is widely used instead of Node’s built-in http module for building applications because it provides a more efficient, flexible, and powerful way to handle routing, middleware, and common web server tasks. Here are the key reasons why Express is preferred over the native http module:

1. Simplified Routing

  • Express: Express makes it very easy to set up routes. You can define routes for different HTTP methods and URL paths in a readable, intuitive way:
app.get('/home', (req, res) => {
  res.send('Welcome to Home Page');
});
app.post('/submit', (req, res) => {
  res.send('Form submitted');
});

  • Native http Module: With http, you have to manually parse the URL and HTTP method to route requests. This quickly becomes complex in larger applications:
const server = http.createServer((req, res) => {
  if (req.method === 'GET' && req.url === '/home') {
    res.end('Welcome to Home Page');
  } else if (req.method === 'POST' && req.url === '/submit') {
    res.end('Form submitted');
  } else {
    res.writeHead(404);
    res.end('Page Not Found');
  }
});

2. Built-in Middleware Support

  • Express: Middleware in Express allows you to add reusable logic (e.g., authentication, parsing, logging) across routes easily. Express has built-in middleware (like express.json() and express.urlencoded()) and allows for custom middleware:
app.use(express.json()); // Parses incoming JSON requests
app.use((req, res, next) => {
  console.log(`${req.method} request for ${req.url}`);
  next();
});
  • Native http Module: In http, there’s no native support for middleware, so you have to manually write or integrate middleware logic. Implementing functionality like body parsing or request logging is time-consuming and repetitive.

3. Easier Request and Response Handling

  • Express: Express provides convenient methods for handling requests and responses, such as res.json() for sending JSON, res.status() for setting status codes, and res.sendFile() for serving files. These methods save time and make the code more readable:
app.get('/data', (req, res) => {
  res.status(200).json({ message: 'Here is your data' });
});
  • Native http Module: With http, setting up responses requires manually setting headers, status codes, and sending the data, which adds extra complexity:
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ message: 'Here is your data' }));

4. Enhanced Error Handling

  • Express: Express has a centralized error-handling mechanism that simplifies error management. You can add error-handling middleware that catches errors and sends a response, making it easier to handle unexpected issues:
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send('Something went wrong!');
});
  • Native http Module: In http, you have to handle errors at each step, which can lead to code duplication and scattered error-handling logic, making it harder to manage errors consistently.

5. Extensibility and Community Packages

  • Express: Express has a vast ecosystem of middleware and third-party packages that provide additional functionality, such as authentication (passport), validation (express-validator), file uploads (multer), and more. This flexibility speeds up development and improves code maintainability.
  • Native http Module: With http, you would need to manually configure or integrate third-party libraries to achieve the same functionalities, which can slow down development.

6. Asynchronous Handling of Requests

  • Express: Express is designed to work well with asynchronous code (e.g., async/await or promises), making it easier to handle asynchronous tasks like database calls within routes and middleware.
  • Native http Module: While the http module also supports asynchronous code, it lacks the built-in utilities and structure provided by Express, making it more challenging to handle asynchronous tasks cleanly.

7. Scalability and Maintainability

  • Express: Express provides a clear structure for organizing routes and middleware, which scales well as applications grow. You can split routes into separate files, use routers for modularity, and implement middleware in a structured manner.
  • Native http Module: Scaling and maintaining large applications in http can become challenging due to the lack of structure and the need for extensive boilerplate code.

Summary

In summary, Express builds on the http module by simplifying routing, adding middleware support, handling requests and responses efficiently, and providing robust error handling and modularity. These features make Express ideal for building applications quickly, managing complexity, and scaling easily compared to the bare http module.