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

前言

用过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

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理