To exclude certain API routes from middlewares in Nestjs, you have to use the exclude()
method of the MiddlewareConfigProxy
interface and pass the route strings or the RouteInfo
object as an argument to the method. The exclude()
is chained after the apply()
method of the MiddlewareConsumer
interface.
TL;DR
Method 1: Excluding API route with all request methods from middlewares
import { MiddlewareConsumer, Module, NestModule } from "@nestjs/common";
import { GreetController } from "./greet/greet.controller";
import { CustomersController } from "./customers/customers.controller";
import { GreetService } from "./greet/greet.service";
import { ApplicationLogger } from "./middlewares/application-logger.middleware";
import { RequestTransformer } from "./middlewares/request-transformer.middleware";
@Module({
imports: [],
controllers: [GreetController, CustomersController],
providers: [GreetService],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
// - `ApplicationLogger` and `RequestTransformer` middlewares
// applied to the `GreetController` and `CustomersController` controllers
// - Exclude the `/customers` API route from the 2 middlewares
// by chaining the `exclude()` method after `apply()` method
// and passing the API route string as an argument to it.
consumer
.apply(ApplicationLogger, RequestTransformer)
.exclude("/customers")
.forRoutes(GreetController, CustomersController);
}
}
Method 2: Excluding API route with a specific request method from middlewares
import {
MiddlewareConsumer,
Module,
NestModule,
RequestMethod,
} from "@nestjs/common";
import { GreetController } from "./greet/greet.controller";
import { CustomersController } from "./customers/customers.controller";
import { GreetService } from "./greet/greet.service";
import { ApplicationLogger } from "./middlewares/application-logger.middleware";
import { RequestTransformer } from "./middlewares/request-transformer.middleware";
@Module({
imports: [],
controllers: [GreetController, CustomersController],
providers: [GreetService],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
// - `ApplicationLogger` and `RequestTransformer` middlewares
// applied to the `GreetController` and `CustomersController` controllers
// - Exclude the `/customers` - `GET` method API route from the 2 middlewares
// by chaining the `exclude()` method after `apply()` method
// and passing the `RouteInfo` object as an argument to it.
consumer
.apply(ApplicationLogger, RequestTransformer)
.exclude({ path: "/customers", method: RequestMethod.GET })
.forRoutes(GreetController, CustomersController);
}
}
For example, let's say we have 2 middlewares called ApplicationLogger
and RequestTransformer
and 2 controllers called GreetController
and CustomersController
.
It will look like this,
import { MiddlewareConsumer, Module, NestModule } from "@nestjs/common";
import { GreetController } from "./greet/greet.controller";
import { CustomersController } from "./customers/customers.controller";
import { GreetService } from "./greet/greet.service";
import { ApplicationLogger } from "./middlewares/application-logger.middleware";
import { RequestTransformer } from "./middlewares/request-transformer.middleware";
@Module({
imports: [],
controllers: [GreetController, CustomersController],
providers: [GreetService],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
// `ApplicationLogger` and `RequestTransformer` middlewares
// applied to the `GreetController` and `CustomersController` controllers
consumer
.apply(ApplicationLogger, RequestTransformer)
.forRoutes(GreetController, CustomersController);
}
}
We aim to exclude the /customers
API route of the CustomersController
controller from both the RequestTransformer
and the ApplicationLogger
middleware.
To do that, we can use the exclude()
after the apply()
method and pass the /customers
API route string as an argument to it.
It can be done like this,
import { MiddlewareConsumer, Module, NestModule } from "@nestjs/common";
import { GreetController } from "./greet/greet.controller";
import { CustomersController } from "./customers/customers.controller";
import { GreetService } from "./greet/greet.service";
import { ApplicationLogger } from "./middlewares/application-logger.middleware";
import { RequestTransformer } from "./middlewares/request-transformer.middleware";
@Module({
imports: [],
controllers: [GreetController, CustomersController],
providers: [GreetService],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
// - `ApplicationLogger` and `RequestTransformer` middlewares
// applied to the `GreetController` and `CustomersController` controllers
// - Exclude the `/customers` API route from the 2 middlewares
// by chaining the `exclude()` method after `apply()` method
// and passing the API route string as an argument to it.
consumer
.apply(ApplicationLogger, RequestTransformer)
.exclude("/customers")
.forRoutes(GreetController, CustomersController);
}
}
The above code will exclude the /customers
API route from the RequestTransformer
and the ApplicationLogger
middleware.
The problem with the above mechanism is you cannot specify the request method for the /customers
API route. The above code will exclude the /customers
API route even if it is a GET
, POST
, DELETE
, etc. method.
To specifically exclude a method of the /customers
API route, you have to pass the RouteInfo
object as an argument to the exclude()
method.
For example, if we want to exclude the GET
method of the /customers
API route, we have to pass the RouteInfo
object as an argument to the exclude()
method.
The RouteInfo
object has 2 keys called path
and method
. The path
key should have the value of the API route string and the method
key should have the appropriate request method value from the RequestMethod
enum. The RequestMethod
enum can be imported from the @nestjs/common
module.
In our case, we need to exclude the /customers
- GET
method API route from the middleware.
It can be done like this,
import {
MiddlewareConsumer,
Module,
NestModule,
RequestMethod,
} from "@nestjs/common";
import { GreetController } from "./greet/greet.controller";
import { CustomersController } from "./customers/customers.controller";
import { GreetService } from "./greet/greet.service";
import { ApplicationLogger } from "./middlewares/application-logger.middleware";
import { RequestTransformer } from "./middlewares/request-transformer.middleware";
@Module({
imports: [],
controllers: [GreetController, CustomersController],
providers: [GreetService],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
// - `ApplicationLogger` and `RequestTransformer` middlewares
// applied to the `GreetController` and `CustomersController` controllers
// - Exclude the `/customers` - `GET` method API route from the 2 middlewares
// by chaining the `exclude()` method after `apply()` method
// and passing the `RouteInfo` object as an argument to it.
consumer
.apply(ApplicationLogger, RequestTransformer)
.exclude({ path: "/customers", method: RequestMethod.GET })
.forRoutes(GreetController, CustomersController);
}
}
We have now excluded the /customers
API route with an appropriate method.
See the above code live in codesandbox.
That's all 😃.