gpt4 book ai didi

【NestJS系列】核心概念:Middleware中间件

转载 作者:我是一只小鸟 更新时间:2023-08-31 07:39:27 34 4
gpt4 key购买 nike

前言

用过 express 与 koa 的同学,对中间件这个概念应该非常熟悉了,中间件可以拿到 Request 、 Response 对象和 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 。

最后此篇关于【NestJS系列】核心概念:Middleware中间件的文章就讲到这里了,如果你想了解更多关于【NestJS系列】核心概念:Middleware中间件的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com