Nest.js中间件进一步理解

Nest.js中,可以用中间件干非常多东西,比如验证所有前端接口的token是否过期,或者如要进行统一的方法,都可以进过中间件。

中间件在Nest.js通过命令创建

nest g middleware xxx 
import { Injectable, NestMiddleware } from '@nestjs/common';

@Injectable()
export class MiddlewareAllMiddleware implements NestMiddleware {
  use(req: any, res: any, next: () => void) {
    console.log('所有组件都进过了middlewareAll这个中间件')
    next();
  }
}

在中间件中req用于处理前端请求,如请求头、请求体等。

在中间件中res用于处理后端给前端发送信息,设置响应的状态码、响应头、响应体等。

在中间件中next方法用于将控制权传递给下一个中间件或路由处理器。当调用next()时,NestJS会按照中间件的顺序执行下一个中间件或路由处理器。如果没有更多的中间件或路由处理器,请求将被结束并发送响应给客户端。

执行顺序先中间件在执行controller中的方法

配置好的中间件需要在在app.module中配置

import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common';
import { AppService } from './app.service';
import { MiddlewareTestController } from './middleware-test/middleware-test.controller';
import { MiddlewareTestMiddleware } from './middleware-test/middleware-test.middleware';
import { MiddlewareNewTestController } from './middleware-new-test/middleware-new-test.controller';
import { MiddlewareAllMiddleware } from './middleware-all/middleware-all.middleware';
import { MiddlewareNewTestMiddleware } from './middleware-new-test/middleware-new-test.middleware';

@Module({
  imports: [],
  controllers: [MiddlewareTestController, MiddlewareNewTestController],
  providers: [AppService],
})

export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(MiddlewareAllMiddleware)
      .forRoutes('*')

      .apply(MiddlewareTestMiddleware)
      .forRoutes({
        path: 'middleware-test',
        method: RequestMethod.ALL
      })
      
      .apply(MiddlewareNewTestMiddleware)
      .forRoutes({
        path: 'middleware-new-test',
        method: RequestMethod.ALL
      })
  }
}

在这里AppModule需要实现NestModule接口中的方法

需要通过@nestjs/common进行导入NestModule

import { NestModule } from '@nestjs/common';

点开NestModule接口可以看见

import { MiddlewareConsumer } from '../middleware/middleware-consumer.interface';
/**
 * @publicApi
 */
export interface NestModule {
    configure(consumer: MiddlewareConsumer): any;
}

他需要我们实现一个configure方法并且接收了MiddlewareConsumer接口定义的一些方法,同时我们也需要在app.module通过@nestjs/common引入MiddlewareConsumer

import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common';

然后使用consumer下的方法需要也需要给consumer进行实现接口的规范

configure(consumer: MiddlewareConsumer) {}

然后就可以使用consumer下的apply方法了,这个是consumer的接口对象

import { Type } from '../type.interface';
import { MiddlewareConfigProxy } from './middleware-config-proxy.interface';
/**
 * Interface defining method for applying user defined middleware to routes.
 *
 * @see [MiddlewareConsumer](https://docs.nestjs.com/middleware#middleware-consumer)
 *
 * @publicApi
 */
export interface MiddlewareConsumer {
    /**
     * @param {...(Type | Function)} middleware middleware class/function or array of classes/functions
     * to be attached to the passed routes.
     *
     * @returns {MiddlewareConfigProxy}
     */
    apply(...middleware: (Type<any> | Function)[]): MiddlewareConfigProxy;
}

.apply方法

.apply方法接收创建好的middlemare实例

import { MiddlewareAllMiddleware } from './middleware-all/middleware-all.middleware';
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(MiddlewareAllMiddleware)
  }
}

在上面.apply方法的源码中,他返回MiddlewareConfigProxy接口,这个接口返回了exclude和forRoutes方法

import { Type } from '../type.interface';
import { RouteInfo } from './middleware-configuration.interface';
import { MiddlewareConsumer } from './middleware-consumer.interface';
/**
 * @publicApi
 */
export interface MiddlewareConfigProxy {
    /**
     * Routes to exclude from the current middleware.
     *
     * @param {(string | RouteInfo)[]} routes
     * @returns {MiddlewareConfigProxy}
     */
    exclude(...routes: (string | RouteInfo)[]): MiddlewareConfigProxy;
    /**
     * Attaches either routes or controllers to the current middleware.
     * If you pass a controller class, Nest will attach the current middleware to every path
     * defined within it.
     *
     * @param {(string | Type | RouteInfo)[]} routes
     * @returns {MiddlewareConsumer}
     */
    forRoutes(...routes: (string | Type<any> | RouteInfo)[]): MiddlewareConsumer;
}

.forRoutes

forRoutes接收多个对象,在源码中可以看到有展开运算符,每个对象需要传入path和method两个属性,

path

path需要写对应的后端controller路由,这个路由可以去执行这个中间件的方法

method

method需要写对应这个controller的那些接口可以进行执行这个中间件,需要通过@nestjs/common导入RequestMethod来配置method

import { RequestMethod } from '@nestjs/common';
RequestMethod.ALL 

配置这个控制器下的所有接口都可以去执行对应的中间件

RequestMethod.GET

配置这个控制器下的GET接口可以去执行对应的中间件

RequestMethod.POST

配置这个控制器下的POST接口可以去执行对应的中间件

........

.apply

在.forRoutes方法下还可以继续.apply因为源码中

import { Type } from '../type.interface';
import { RouteInfo } from './middleware-configuration.interface';
import { MiddlewareConsumer } from './middleware-consumer.interface';
/**
 * @publicApi
 */
export interface MiddlewareConfigProxy {
    /**
     * Routes to exclude from the current middleware.
     *
     * @param {(string | RouteInfo)[]} routes
     * @returns {MiddlewareConfigProxy}
     */
    exclude(...routes: (string | RouteInfo)[]): MiddlewareConfigProxy;
    /**
     * Attaches either routes or controllers to the current middleware.
     * If you pass a controller class, Nest will attach the current middleware to every path
     * defined within it.
     *
     * @param {(string | Type | RouteInfo)[]} routes
     * @returns {MiddlewareConsumer}
     */
    forRoutes(...routes: (string | Type<any> | RouteInfo)[]): MiddlewareConsumer;
}

forRoutes方法返回了MiddlewareConsumer 而MiddlewareConsumer正好是apply所对应的接口,从而得以继续.apply下去,这样可以进行多个middleware的配置

全部代码

讲到不到位请多包涵,博主也是新手小白

import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common';
import { AppService } from './app.service';
import { MiddlewareTestController } from './middleware-test/middleware-test.controller';
import { MiddlewareTestMiddleware } from './middleware-test/middleware-test.middleware';
import { MiddlewareNewTestController } from './middleware-new-test/middleware-new-test.controller';
import { MiddlewareAllMiddleware } from './middleware-all/middleware-all.middleware';
import { MiddlewareNewTestMiddleware } from './middleware-new-test/middleware-new-test.middleware';

@Module({
  imports: [],
  controllers: [MiddlewareTestController, MiddlewareNewTestController],
  providers: [AppService],
})

export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(MiddlewareAllMiddleware)
      .forRoutes('*')

      .apply(MiddlewareTestMiddleware)
      .forRoutes({
        path: 'middleware-test',
        method: RequestMethod.ALL
      })

      .apply(MiddlewareNewTestMiddleware)
      .forRoutes({
        path: 'middleware-new-test',
        method: RequestMethod.ALL
      })
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值