How to exclude certain API routes from middlewares in Nestjs?

February 16, 2023 - 5 min read

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 😃.