Introduction
When creating APIs in Nest.js, you establish an endpoint for users to send their HTTP requests to. However, sometimes we need to manipulate the data sent by the user before it reaches our route handler function, or perhaps we want to log the data we will send as a response. This is where middlewares come into play.
Middlewares can perform various tasks; however, it's important to note that after creating and registering a middleware, it only executes before a HTTP request reaches the route handler function.
Talk is cheap, let's start coding!
Basic Middleware
For creating middleware in Nest.js, there are two approaches: class-based and function-based. Here, I'll demonstrate the class-based method.
In your Nest.js project, create a file named logger.middleware.ts
and include the following base code:
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
// Other stuff...
}
}
At first glance, it might seem intimidating to those new to Nest.js, but I promise it's straightforward. Now, let's break down the important parts:
LoggerMiddleware
is a class that implements the NestMiddleware
interface. This interface requires the implementation of a function called use()
, where both the Request
and Response
objects are available for use.
When a middleware is invoked, the code within the use()
method is executed. This allows you to leverage the Request
and Response
objects for various purposes. Below is an example of a simple logger middleware:
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
console.log(`Executing middleware in path ${req.path}`);
next();
}
As demonstrated, you have full control over the request object before it reaches the endpoint. The essential part of a middleware is the next()
function, which should be called after at the end to ensure the application continues running smoothly.
Attaching The Middleware
You can't register the middleware using the @Module
decorator. Instead, you need to utilize a method called configure()
within the module class. Additionally, the module class should implement the NestModule interface.
import {
MiddlewareConsumer,
Module,
NestModule,
RequestMethod
} from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { LoggerMiddleware } from './logger.middleware';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware) // if more that one split with ','
.forRoutes({ path: '*', method: RequestMethod.ALL });
}
}
"The main aspect is that you have to apply your middleware class with the to the consumer. You can specify which endpoints and request methods should invoke the middleware. In this example, all endpoints and request methods will trigger the middleware. I highly recommend reading the official Nest.js documentation for more information on this.
Conclusion
In conclusion, mastering the art of middleware usage, whether class-based or function-based, allows you to tailor your application's behavior to your specific requirements. By understanding how to attach middlewares and configure them within your modules, you can unlock the full potential of Nest.js and create robust, efficient APIs.
Top comments (2)
Such useful information
Great Job
Good Job bro