关于前端:NestJS系列核心概念Middleware中间件

38次阅读

共计 2571 个字符,预计需要花费 7 分钟才能阅读完成。

前言

用过 expresskoa的同学,对中间件这个概念应该十分相熟了,中间件能够拿到 RequestResponse 对象和 next 函数.

一般来讲中间件有以下作用:

  • 执行任何代码
  • 对申请与响应拦挡并革新
  • 完结 request-response 周期
  • 通过 next() 调用下一个中间件
  • 如果以后中间件没有完结以后 request-response 周期,必须调用 next() 函数,否则申请会处于挂起状态,阻塞整个利用

中间件个别有两种:类中间件 函数中间件

类中间件

创立类中间件

应用 @Injectable() 装璜器,并且须要实现 NestMiddleware 接口(use办法)

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

@Injectable()
export class LoggerMiddleware implements NestMiddleware {use(req: Request, res: Response, next: () => void) {console.log('logger middleware', `url: ${req.url}`);
        next();}
}

应用类中间件

类两头创立完之后,须要在模块中进行挂载,但 @Module 装璜器并没有中间件的相干配置,咱们须要让 module 类实现 NestModule 接口,实现外面 configure 办法来进行挂载

// user.module.ts
import {Module, NestModule} from '@nestjs/common';
import {UserService} from './user.service';
import {UserController} from './user.controller';
import {LoggerMiddleware} from '../middleware/Logger.middleware';
@Module({controllers: [UserController],
  providers: [UserService]
})
export class UserModule implements NestModule {configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes(UserController);
  }
}
  • apply办法示意挂载的是哪个中间件
  • forRoutes办法示意对哪个申请门路起作用,这种形式与 app.use(path, middleware) 作用是一样,只针对局部门路起作用
  • 当给 forRoutes 办法传递的是一个 controller 控制器时,那么该中间件则对整个控制器下的门路失效

比方这里传递的是 UserController 控制器,那么针对该控制器下的门路都会失效

  • forRootes办法还能做更具体的配置,比方能够针对特定的申请办法、申请门路能够应用正则匹配(须要留神的是应用 fastify 驱动不能应用)
export class UserModule implements NestModule {configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({path: 'user', method: RequestMethod.GET});
  }
}
  • apply能够同时挂载多个中间件
export class UserModule implements NestModule {configure(consumer) {
    consumer
      .apply(LoggerMiddleware, aaaMiddleware, ...)
      .forRoutes({path: 'user', method: RequestMethod.GET});
  }
}
  • forRoutes能够应用单个 string 门路,多个 string 门路,RouteInfo对象,单个Controller,多个Controller
export class AppModule implements NestModule {configure(consumer) {
    consumer
      .apply(LoggerMiddleware, NjMiddleware, ...)
      .forRoutes(UserController, NjController, ...);
  }
}
  • exclude能够用来排除不应用中间件的门路
export class UserModule implements NestModule {configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .exclude({path: '/user/a', method: RequestMethod.GET})
      .forRoutes(UserController);
  }
}

须要留神的是 forRoutes 须要最初调用

函数中间件

这种形式较为简单,应用起来与类中间件统一

创立函数中间件

export function LoggerMiddleware(req: Request, res: Response, next: () => void) {console.log('logger middleware', `url: ${req.url}`);
    next();}

应用函数中间件

export class UserModule implements NestModule {configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .exclude({path: '/user/a', method: RequestMethod.GET})
      .forRoutes(UserController);
  }
}

全局中间件

能够间接在入口文件 main.ts 中应用 app.use 来挂载中间件,这样挂载的中间件将全局失效

app.use(LoggerMiddleware) // 日志中间件

中间件其实能够用来实现很多性能,比方:日志零碎、cors 跨域解决、图片防盗等 …

对图片防盗感兴趣的能够看我这篇文章:你不晓得的 HTTP Referer

正文完
 0