Stay tuned for the NestJs Journey series

The middleware

Middleware is a function called before the routing handler. Middleware functions can access request and response objects.

Those of you who have used KOA and Express should know that middleware is a core feature, especially KOA. The core is middleware, and even routing is provided by middleware.

Middleware can provide the following functions:

  • Execute arbitrary code during execution
  • Make changes to requests and responses
  • End the response to this request
  • Move on to the next middleware call

The sample

NestJs decorates middleware with @Injectable(), and decorates objects that implement the NestMiddleware interface.

Here is an implementation of logging middleware:

// log.middleware.ts
import {Injectable, NestMiddleware} from '@nestjs/common';
import {Request, Response} from 'express';

@Injectable(a)export class LogMiddleware implements NestMiddleware {
    use(req: Request, resp: Response, next: Function) {
        console.log(`${req.method} ${req.path}`) next(); }}Copy the code
// app.module.ts
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LogMiddleware } from './common/middleware/log.middleware';
import { UserModule } from './user/user.module';

@Module({
  imports: [UserModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LogMiddleware)
      .forRoutes('users'); }}Copy the code

Apply middleware to request methods

The simple example above applies the middleware to all Users routes. If you need to apply the middleware only to specific request methods, such as GET requests, you can do this:

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LogMiddleware } from './common/middleware/log.middleware';
import { UserModule } from './user/user.module';

@Module({
  imports: [UserModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LogMiddleware)
       .forRoutes({ path: 'users', method: RequestMethod.GET }); }}Copy the code

Apply multiple Middleware

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LogMiddleware } from './common/middleware/log.middleware';
import { UserModule } from './user/user.module';

@Module({
  imports: [UserModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LogMiddleware, OtherMiddleware)
       .forRoutes({ path: 'users', method: RequestMethod.GET }); }}Copy the code

Apply middleware based on controller name

The above code applies middleware to fixed routing addresses. In NestJs, routing addresses are defined by decorators. If the routing address of the controller changes and the middleware does not change, it will cause problems.

NestJs provides controller-based registration when using middleware:

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LogMiddleware } from './common/middleware/log.middleware';
import { UserModule } from './user/user.module';

@Module({
  imports: [UserModule],
})
export class AppModule implementsNestModule { configure(consumer: MiddlewareConsumer) { consumer .apply(LogMiddleware) .forRoutes(UserController); }}Copy the code

Exclude specified routes

Some scenarios require bypassing several of these methods when middleware is applied to the controller, such as login authentication middleware should allow login routes, otherwise no one will be able to login successfully.

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LogMiddleware } from './common/middleware/log.middleware';
import { UserModule } from './user/user.module';

@Module({
  imports: [UserModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LogMiddleware)
      .exclude(
          {path:'users/login',method:RequestMethod.GET} ) .forRoutes(UserController); }}Copy the code

Global middleware

Similar to global modules, middleware can also be registered globally, taking effect for each route.

// main.ts
const app = await NestFactory.create(AppModule);
app.use(LogMiddleware);
await app.listen(3000);
Copy the code

At the end

Middleware gives the framework great flexibility and can be abstracted into middleware according to functions to achieve the purpose of “pluggable”.

If you feel that you have gained something, share it with more friends in need, thank you!

If you want to exchange more knowledge about NestJs, welcome to add group discussion!