Comprehensive Guide to Servers and Express.js: Basics, Benefits, and Best Practices

What is server ?

A server is a computation machine(hardware + software) which fulfills the requests made by the Clients over a network remotely. need of server, because it provides following things :

  1. Centralized Resource Management : Servers act as a centralized point for managing and distributing resources like files, databases, or applications.

  2. Accessibility : Servers allow resources and services to be accessed remotely over the internet or a local network.

  3. Communication : Servers facilitate communication between clients.

  4. Security : Servers provide a centralized point for implementing security measures like authentication, encryption, and data backup.

What is Express.js ?

  • Express.js is a minimal and flexible web application framework for Node.js.

  • It is designed to build web applications and APIs efficiently and effectively.

  • Express.js simplifies the process of creating robust server-side applications by providing an abstraction over Node.js’s HTTP module and middleware capabilities.

Why Express.js ?

There are many reasons why we can prefer Express.js over other in order to write a server side of application.

  1. Minimalistic and Unopinionated : Provides basic functionalities and leaves decisions( means Unopinionated ) about architecture and tools to developers.

  2. Middleware support : Middleware functions in Express.js are functions that have access to the request object (req), response object (res), and the next middleware function in the application’s request-response cycle. Middleware is used for logging, authentication, error handling, and more.

  3. Routing : Express provides a powerful and flexible routing system to define application endpoints and handle HTTP methods like GET, POST, PUT, DELETE, etc.

  4. Static File Serving : Allows serving of static files like images, CSS, and JavaScript files.

  5. Scalability : Can handle a variety of use cases, from small single-page applications to large RESTful APIs.

  6. Full Stack Development : Integrates seamlessly with front-end frameworks like React, Angular, and Vue.

  7. Community support : Strong community and a rich ecosystem of middleware, extensions, and tools.

Installation :

Follow this link to install the express.js it is very easy :

https://expressjs.com/en/starter/installing.html

How express.js works ?

  1. Server intialization : Express initializes a server to listen for incoming requests.

    You create an Express application using:

     const express = require('express');
     const app = express();
    

    The app object represents your Express application and is used to configure routes, middleware, and responses.

  2. Listening for Requests : The app.listen() method starts the server and listens for incoming HTTP requests on a specified port.

     app.listen(3000, () => {
       console.log('Server running at http://localhost:3000');
     });
    
  3. Middleware Execution : Express uses a middleware system that allows you to execute functions at various stages of the request-response lifecycle.

    • Middleware functions take three arguments:
      (req, res, next):

      • req: The HTTP request object.

      • res: The HTTP response object.

      • next: A callback to pass control to the next middleware in the stack.

Middleware can:

  1. Log information.

  2. Modify requests.

  3. Authenticate users.

  4. Handle errors.

  5. Serve static files.

     app.use((req, res, next) => {
       console.log(req.body.data);
       next(); // Pass control to the next middleware
     });
    
  1. Routing : Routes are defined to handle specific HTTP methods (GET, POST, PUT, DELETE, etc.) and paths. Each route specifies what action to perform when a request matches its criteria or endpoint.

    Example of a GET route:

     app.get('/', (req, res) => {
       res.send('Hello, World!');
     });
    

    In this example, when a client sends a GET request to /, this route is matched, and the response 'Hello, World!' is sent.

  2. Request handling : When a client sends a request to the server, Express:

    1. Matches the request path and HTTP method with the defined routes.

    2. Passes the request through middleware (if any are defined).

    3. Processes the request and tries to fulfill what asked through request.

    4. Sends a response using the res object.

  3. Response : we use the res object to send responses back to the client.

    Common response methods:

    • res.send() - Sends text or HTML.

    • res.json() - Sends a JSON response.

    • res.status(code) - Sets the HTTP status code.

    • res.redirect(url) - Redirects the client to another URL.

        app.get('/success', (req, res) => {
          res.status(200).send('Operation Successful');
        });
      
  4. Error handling : Express has built-in support for error handling. Middleware functions designed for error handling should have four arguments: (err, req, res, next).

     app.use((err, req, res, next) => {
       console.error(err.stack);
       res.status(500).send('Something went wrong!');
     });
    
  5. Static File Serving : To serve static files such as images, CSS files, and JavaScript files, use the express.static built-in middleware function in Express.

     // Syntax
     express.static(root, [options])
    
     // for ex. :  use the following code to serve images, CSS files,
     // and JavaScript files in a directory named public:
     app.use(express.static('public'))
    

Two must to know HTTP method :

  1. GET :

    1. Purpose :

      • GET is used to request data from a specified resource.

      • It is designed to retrieve information and should have no other effect.

    2. Data Submission :

      • Data is appended to the URL as query parameters.

      • Limited amount of data can be sent because the data is included in the URL, and URL have some maximum information

    3. Visibility :

      • Parameters are visible in the URL, which can impact security when dealing with sensitive information.
    4. Caching :

      • Requests can be cached by the browser, and URLs can be bookmarked.

      • It is idempotent, meaning multiple identical requests will have the same effect as a single request.

        const express = require('express');
        const app = express();
        const port = 3000;

        // Define a simple GET route
        app.get('/', (req, res) => {
          res.send('Hello, this is a GET request!');
        });

        // Define a route with a parameter
        app.get('/greet/:name', (req, res) => {
          const { name } = req.params;
          res.send(`Hello, ${name}!`);
        });

        // Start the server
        app.listen(port, () => {
          console.log(`Server is running on http://localhost:${port}`);
        });

POST :

  1. Purpose:

    • POST is used to submit data to be processed to a specified resource.

    • It can be used to create or update a resource on the server.

  2. Data Submission:

    • Data is sent in the request body, not in the URL.

    • Can send a large amount of data compared to GET.

  3. Visibility:

    • Parameters are not visible in the URL, enhancing security.
  4. Caching:

    • Requests are not cached by the browser, and URLs cannot be bookmarked.

    • It is not idempotent; multiple identical requests may have different effects.

Before handling POST requests, it's important to include middleware to parse the incoming data. Express provides built-in middleware for handling JSON and form data. Add the following middleware to your Express app:

// Middleware to parse JSON and form data
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

handling post request :

const express = require('express');
const app = express();

// Middleware to parse JSON body
app.use(express.json()); // Allows Express to parse JSON payloads

// POST route
app.post('/submit', (req, res) => {
  const { name, email } = req.body; // Extract data from the request body
  res.send(`Received data: Name - ${name}, Email - ${email}`);
});

// Start the server
app.listen(3000, () => {
  console.log('Server running at http://localhost:3000');
});

Middleware :

Middleware is a function in Express.js that has access to the request object (req), the response object (res), and the next middleware function (next) in the application’s request-response cycle. Middleware is used to modify, process, or handle requests before they reach the intended route handler or send a response back to the client.

Characterstics :

  1. Receives three parameters:

    • req: Represents the HTTP request object.

    • res: Represents the HTTP response object.

    • next: A function to pass control to the next middleware.

  2. Order Matters: Middleware functions are executed in the order they are defined in the code.

  3. Chaining: Middleware can pass control to the next middleware or route handler using the next() function.

  4. Use Cases: Middleware is used for:

    • Authentication and authorization.

    • Logging and monitoring.

    • Parsing incoming requests (e.g., JSON, form data).

    • Serving static files.

    • Error handling.

Ways to Send the Inputs to a Requests :

  1. Query Parameter : uses key value or variable in the url to pass the specific instruction.

  2. Body : hidden part of the request, carrying most of the details about the request and everything.

    • example: When you fill out a form on a website, the details you enter (name, email) go in the body of the request.
  3. Headers : Extra information attached to the request, kind of like details about a letter.

    • example : Headers could include things like your identity or the type of data you're sending.

Global catches :

Global Catch or Error-Handling Middleware is a special type of middleware function in Express that has four arguments instead of three ((err, req, res, next)). Express recognizes it as an error-handling middleware because of these four arguments.

// Error Handling Middleware
const errorHandler = (err, req, res, next) => {
  console.error('Error:', err);
  // Customize the error response based on your requirements
  res.status(500).json({ error: 'Something went wrong!' });
};

Benefits of global catches :

  1. Centralized Handling:

    • Global catch blocks allow you to centrally manage and handle errors that occur anywhere in your application. Instead of handling errors at each specific location, you can capture and process them in a centralized location.
  2. Consistent Error Handling:

    • Using a global catch mechanism ensures a consistent approach to error handling throughout the application. You can define how errors are logged, reported, or displayed in one place, making it easier to maintain a uniform user experience.
  3. Fallback Mechanism:

    • Global catches often serve as a fallback mechanism. If an unexpected error occurs and is not handled locally, the global catch can capture it, preventing the application from crashing and providing an opportunity to log the error for further analysis.