What is Express.js?

overview

Express.js is a Node.js web framework designed to help developers efficiently create web applications.

Key features of Express.js include routing, request and response handling, and middleware support. It also allows developers to easily extend its functionality through the use of middleware, which can be described as plugins.

Here, we will introduce the basic usage of Express.js using the following versions.

Express.js v6.0.0
Node.js v19.7.0

Basic Concepts of Express.js

Routing

Routing is a mechanism for receiving HTTP requests from clients and processing them accordingly. Express.js allows you to use its routing capabilities to gracefully handle requests for different URL paths and HTTP methods.

const express = require('express');

const app = express();

// define route for GET method
app.get('/', (req, res) => {
  res.send('Hello, world!');
});

// Define route for POST method
app.post('/users', (req, res) => {
  const { name, email } = req.body;
  // process user data and return response
  res.send({ message: `User created: ${name} (${email})` });
});

// route definition with parameters
app.get('/users/:id', (req, res) => {
  const userId = req.params.id;
  // get user data from a database or other source
  const user = { id: userId, name: 'Taro Yamada' };
  res.send(user);
});

// start the server
app.listen(3000, () => {
  console.log('Server started on port 3000');
});

Middleware

Express.js allows you to create middleware and implement processing for each request.

const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');

const app = express();

// CORS settings
app. use(cors());

// Middleware for parsing JSON requests
app.use(bodyParser.json());

// define route for GET method
app.get('/', (req, res) => {
  res.send('Hello, world!');
});

// Define route for POST method
app.post('/users', (req, res) => {
  const { name, email } = req.body;
  if (!name || !email) {
    res.status(400).send('Name and email are required');
  } else {
    // store and process data
    saveUserData(name, email);
    res.send({ message: `User created: ${name} (${email})` });
  }
});

// route definition with parameters
app.get('/users/:id', (req, res) => {
  const userId = req.params.id;
  // get user data from a database or other source
  const user = { id: userId, name: 'Taro Yamada' };
  res.send(user);
});

// start the server
app.listen(3000, (err) => {
  if (err) {
    console.error('An error occurred while starting the server:', err);
    process.exit(1);
  }
  console.log('Server started on port 3000');
});

// Example of an asynchronous function that retrieves data from the database
async function getDataFromDatabase() {
  // Execute database access asynchronous processing
  return await db.query('SELECT * FROM users');
}

// Example of processing to save user data
function saveUserData(name, email) {
  // data save processing
  // ...
}

This example uses the express, cors and body-parser packages.

We pass the cors() function to the app.use() method to enable CORS protection. This setting allows requests from all origins and enables CORS for all HTTP methods. If you want to configure more detailed CORS settings, you can pass an options object to the cors() function.

The body-parser.json() middleware converts JSON data obtained as input into a JavaScript object.

Handler

In Express.js, handler functions define what to do with routed requests. A handler is responsible for receiving a request, performing the necessary processing, and returning a response.

Below is an example handler in Express.js.

const express = require('express');
const app = express();
app.use(express.json());

// define a handler for the GET method
app. get('/', async (req, res) => {
  try {
    // Execute an asynchronous function to process the request
    const data = await getDataFromDatabase();
    res.send(data);
  } catch (error) {
    console.error('An error has occurred:', error);
    res.status(500).send('An error has occurred');
  }
});

// define handler for POST method
app.post('/users', (req, res) => {
  const { name, email } = req.body;
  // process user data
  if (!name || !email) {
    res.status(400).send('Name and email are required');
  } else {
    // store and process data
    saveUserData(name, email);
    res.send({ message: `User created: ${name} (${email})` });
  }
});

// start the server
app.listen(3000, (err) => {
  if (err) {
    console.error('An error occurred while starting the server:', err);
    process.exit(1);
  }
  console.log('Server started on port 3000');
});

// Example of an asynchronous function that retrieves data from the database
async function getDataFromDatabase() {
  // Execute database access asynchronous processing
  return await db.query('SELECT * FROM users');
}

// Example of processing to save user data
function saveUserData(name, email) {
  // data save processing
  // ...
}

The example above defines handlers for the GET and POST methods. The GET method handler uses an asynchronous function to retrieve data from the database and return it as a response. The POST method handler obtains the necessary data from the request body and performs validation and data storage processing.

In the handler function, process the request asynchronously

It uses async and await in some cases, and try-catch syntax for error handling. If an error occurs, the appropriate status code and error message are returned as a response.

The above is an example of a handler in Express.js. This allows you to implement any logic you want inside the handler function, such as handling requests or manipulating data.

Middleware

I will explain the concept of middleware in Express.js with examples of using middleware.

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

const app = express();

// register middleware
app. use(cors({
  origin: '*',
  methods: ['GET', 'POST'],
}));

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

// start the server
app.listen(3000, (err) => {
  if (err) {
    console.error('An error occurred while starting the server:', err);
    process.exit(1);
  }
  console.log('Server started on port 3000');
});

In the example above, we use the cors middleware to add CORS (Cross-Origin Resource Sharing) functionality to our Express application. Register the middleware using the app.use() method and specify the desired options.

This example uses the cors middleware to allow requests from all origins and only GET and POST methods. This allows your application to make cross-origin requests.

Middleware is a convenient way to add or customize functionality. There is a wide variety of middleware in the Express.js ecosystem to easily add features such as authentication, logging, database connectivity, and more. This allows you to extend the functionality of your application as needed.

Schema and Validation

Express.js itself does not have a built-in validation function, but generally you use a validation library like joi or express-validator to validate request parameters, bodies, and query parameters. increase. This allows you to easily check the integrity of your input data.

Response handling: Express.js also offers flexibility in handling responses. For example, you can return responses in different formats. Express.js supports different types of responses such as JSON, HTML, and binary data.

const express = require('express');
const { check, validationResult } = require('express-validator');

const app = express();
app.use(express.json());

// Define user data validation rules
const userValidators = [
  check('name').isString(),
  check('age').isInt({ min: 0 }),
  check('email').isEmail(),
];

// Define route and apply validation for POST method
app.post('/users', userValidators, (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }
  
  const { name, age, email } = req.body;

  // process user data
  const userData = { name, age, email };

  // send response
  res.json(userData);
});

// start the server
app.listen(3000, (err) => {
  if (err) {
    console.error('An error occurred while starting the server:', err);
    process.exit(1);
  }
  console.log('Server started on port 3000');
});

In the above example, we are using express-validator to validate the request. An array called userValidators defines the user data validation rules. Each field specifies a data type and validation rules.

The route definition for the POST method uses userValidators as middleware to set the validation of the request body. Verifies whether the request body data conforms to the validation rules.

inside the handler, the request body’s de

fetching data and processing user data. When sending processing result data as a response, Express.js automatically generates the response in JSON format.

Express.js also allows flexibility in handling responses. For example, if you send an object or array using the res.json() method, Express.js will automatically convert it to JSON format and return it to the client. Additionally, Express.js supports different types of responses, allowing you to create custom responses such as HTML or binary data.

This allows you to use Express.js to validate requests and generate flexible responses.

Processing the response

Express.js also allows flexibility in handling responses. For example, you can return responses in different formats. Express.js supports different types of responses such as JSON, HTML, and binary data.

Let’s discuss response handling with code examples that return different formats of responses in Express.js.

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

const app = express();

// JSON response example
app.get('/api/users', (req, res) => {
  const users = [
    { id: 1, name: 'John Doe' },
    { id: 2, name: 'Jane Smith' },
    { id: 3, name: 'Bob Johnson' }
  ];
  res.json(users);
});

// HTML response example
app.get('/about', (req, res) => {
  const htmlContent = `
    <html>
      <head>
        <title>About Us</title>
      </head>
      <body>
        <h1>About Us</h1>
        <p>Welcome to our website!</p>
      </body>
    </html>
  `;
  res.send(htmlContent);
});

// binary data example
app.get('/image', (req, res) => {
  const imagePath = path.join(__dirname, 'path/to/image.jpg');
  res.sendFile(imagePath);
});

// start the server
app.listen(3000, (err) => {
  if (err) {
    console.error('An error occurred while starting the server:', err);
    process.exit(1);
  }
  console.log('Server started on port 3000');
});

The above examples show how to return responses in different formats.

  1. JSON response example: A GET request to the /api/users path will return a response containing user data in JSON format.

  2. HTML response example: A GET request to the /about path will return a response containing HTML content. I am sending HTML using res.send().

  3. Binary data example: If there is a GET request to the /image path, the binary data of the specified image file will be returned as a response. I am sending the file using res.sendFile().

As you can see from these examples, Express.js supports different types of responses. Also, you can easily return a response by using res.json(), res.send(), res.sendFile(). It is also possible to specify the content type if necessary.

Features of Express.js

Asynchronous processing and event-driven architecture:

Express.js also employs asynchronous processing and an event-driven architecture leveraging Node.js’s EventEmitter. This allows requests to be processed in parallel at the same time. Compared to traditional synchronous web frameworks, Express.js offers asynchronous processing flexibility and efficiency. With its event-driven architecture, Express.js takes full advantage of the event loop’s properties to efficiently handle asynchronous processing of requests. This allows multiple requests to be processed simultaneously, resulting in faster response times and better scalability.

Resource Optimization with Middleware Support

Express.js leverages intermediates for handling HTTP requests and responses. This makes it easy to specify functions to run within the request and response lifecycle.

In addition, Express.js also focuses on resource optimization. Detail optimizations such as dependency management and memory usage optimizations. This allows Express.js applications to work efficiently and provide scalable performance.

Documentation is available on the official website, so let’s check how good it is.

High scalability

Express.js leverages the concept of middleware and is easily customizable and extensible. By using a large number of middleware, it becomes easy to add functions and incorporate modules. Also, middleware can be added or removed without restarting the application.

Simple handling of requests and responses

Express.js simplifies request and response handling

to=User<|im_sep|>## Characteristics of Express.js

Intermediate processing and event-driven architecture:

Express.js employs intermediate processing and an event-driven architecture leveraging Node.js’s EventEmitter. This makes it possible to chain the processing of requests. Compared to traditional synchronous web frameworks, Express.js is more flexible and efficient in intermediate processing. With its event-driven architecture, Express.js takes full advantage of the event loop’s properties to efficiently handle intermediate processing of requests. This allows multiple requests to be processed serially, resulting in faster response times and better scalability.

Low overhead and resource optimization

Express.js is a very lightweight framework that minimizes the overhead required to handle HTTP requests and responses. This allows efficient use of system resources and can effectively respond to server load.

In addition, Express.js also focuses on resource optimization. Detail optimizations such as dependency management and memory usage optimizations. This allows Express.js applications to run fast and efficiently, providing highly scalable performance.

Let’s check the benchmark published on the official website to see how good it is.

Excellent scalability

Express.js has a middleware system that can be easily customized and extended. Using various middleware makes it easy to add functionality and incorporate modules. Also, middleware can be added or removed without restarting the application.

Asynchronous processing and event-driven architecture:

Express.js also employs asynchronous processing and an event-driven architecture leveraging Node.js’s EventEmitter. This allows requests to be processed in parallel at the same time. However, compared to Fastify, Express.js can show some differences in speed and efficiency. With its event-driven architecture, Express.js also leverages the properties of the event loop to efficiently handle asynchronous processing of requests. Multiple requests can be processed simultaneously, but compared to Fastify, there is a difference in response time reduction and scalability.

Low overhead and resource optimization

Express.js is also a very lightweight framework, minimizing the overhead required to handle HTTP requests and responses. Compared to Fastify, Express.js is a bit more procedural when it comes to resource optimization.

Express.js also puts a lot of effort into managing dependencies and optimizing memory usage. However, compared to Fastify, there are differences in overall performance and scalability.

Excellent scalability

Express.js also has extensibility in the form of middleware. Using various middleware makes it easy to add functionality and incorporate modules.

Validation

Express.js doesn’t have a strict schema-based validation system like Fastify does, and validation is mostly done using middleware.

Rich ecosystem and documentation

Express.js’ strength lies in its rich ecosystem and detailed documentation. It supports a wide range of users from beginners to advanced users.

Express.js vs Fastify

Express.js and Fastify are each popular Node.js-based web frameworks, but each has its own peculiarities. In this article, we’ll compare Express.js and Fastify and take a closer look at each framework’s benefits and appropriate use cases.

Speed ​​and efficiency

Express.js is popular as a concise and highly optimized framework. Asynchronous processing and an event-driven architecture allow many requests to be processed in parallel. On the other hand, Fastify is also known for its speed, although it is slightly faster than Express.js. Fastify is especially strong in situations where low overhead and fast performance are required.

Conclusion: Express.js is fast, reliable and provides good performance in many scenarios.

Extensibility and Middleware Ecosystem

Express.js is known for its extensibility. Using middleware makes it easy to add and customize functions. There are a myriad of middlewares in the ecosystem that can add functionality such as authentication, logging, database connectivity, and more.

On the other hand, Fastify also has a powerful plugin system, but compared to Express.js, there may be fewer plugin types and choices.

Conclusion: Express.js offers a powerful and diverse middleware ecosystem and is highly extensible.

Learning curve and speed of development

Express.js offers a simple and intuitive API with a very short learning curve. This allows you to start new projects quickly and build applications quickly.

On the other hand, Fastify is also a powerful framework, but its advanced features and optimizations may require a deeper understanding and learning.

Conclusion: Express.js is a learning

While the curve is short and development speed fast, Fastify may have a slightly steeper learning curve in its quest for high performance.

Use case

Express.js is suitable for many uses such as simple web applications, API servers, monolithic applications, etc. By leveraging middleware, custom functionality can be easily added to meet specific requirements.

Fastify, on the other hand, is particularly well-suited for scenarios that require high performance, such as high-load situations and real-time data processing.

Conclusion: While Express.js is versatile, Fastify is particularly well-suited for situations where high performance is required.

summary

Express.js is widely used by web developers for its simplicity, reliability, and rich middleware ecosystem. Express.js is a framework that is flexible enough for a wide range of use cases and accessible to beginners.

On the other hand, Fastify is also a powerful framework, and its speed, scalability, and detailed features for optimization make it very useful in certain scenarios. However, its powerful capabilities may require more detailed knowledge and understanding.

Overall, which framework to choose depends a lot on your specific requirements, development environment, and goals.