Express.js is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications. One of the core concepts in Express.js is middleware functions, which are functions that have access to the request object (req), the response object (res), and the next middleware function in the application’s request-response cycle.
Middleware functions can execute any code, make changes to the request and the response objects, end the request-response cycle, and call the next middleware function in the stack. If the current middleware function does not end the request-response cycle, it must call next() to pass control to the next middleware function. Otherwise, the request will be left hanging.
Middleware functions are defined as follows:
function myMiddleware(req, res, next) {
// Perform operations on req and/or res
console.log('Middleware executed');
// Call the next middleware function in the stack
next();
}
In Express.js, you can use `app.use()` to bind middleware functions to your application. Middleware functions are executed sequentially, so the order in which they are added matters.
## Examples
### Basic Middleware Example
Let's create a simple Express application with a basic middleware function that logs a message every time a request is made.
```javascript
import express from 'express';
const app = express();
const PORT = 3000;
// Define a basic middleware function
function logRequest(req, res, next) {
console.log(`Received \${req.method} request for \${req.url}`);
next(); // Pass control to the next middleware function
}
// Use the middleware function
app.use(logRequest);
// Define a route
app.get('/', (req, res) => {
res.send('Hello World!');
});
// Start the server
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:\${PORT}`);
});
When you run this application and navigate to http://localhost:3000, you should see the following output in your terminal:
Received GET request for /
Hello World!
Error-handling middleware functions have an additional argument: the error object. These functions are defined with four arguments instead of three, and they must be added after all other app.use() and route calls.
Here's an example of an error-handling middleware function:
import express from 'express';
const app = express();
const PORT = 3000;
// Define a basic middleware function
function logRequest(req, res, next) {
console.log(`Received \${req.method} request for \${req.url}`);
next(); // Pass control to the next middleware function
}
// Use the middleware function
app.use(logRequest);
// Define a route that throws an error
app.get('/error', (req, res) => {
throw new Error('Something went wrong!');
});
// Define an error-handling middleware function
function errorHandler(err, req, res, next) {
console.error(err.stack);
res.status(500).send('Something broke!');
}
// Use the error-handling middleware function
app.use(errorHandler);
// Start the server
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:\${PORT}`);
});
When you navigate to http://localhost:3000/error, you should see the following output in your terminal:
Received GET request for /error
Error: Something went wrong!
at ...
Something broke!
In this tutorial, we covered the basics of middleware functions in Express.js and how to use them. In the next section, we will explore error handling in Express.js, which is crucial for building robust applications.
Stay tuned for more tutorials on Express.js!