美文网首页
Nest.js - Middleware

Nest.js - Middleware

作者: stevekeol | 来源:发表于2020-07-10 16:18 被阅读0次
    中间件的介绍
    • 中间件是在理由处理程序之前调用的函数。
    • 中间件函数可以访问请求对象响应对象,以及请求响应周期中的next()中间件函数
    • Nest中间件实际上就是底层Express中间件

    中间件函数可以执行以下任务:

    • 执行任何代码
    • 请求和响应对象进行更改
    • 结束请求-响应周期
    • 调用堆栈中的下一个中间件函数
    • 如没有结束请求-响应周期,那么必须调用next()将控制交给下一个中间件函数,否则请求将被挂起
    自定义中间件的实现
    • 普通函数中实现Nest中间件
    • 具有 @Injectable() 装饰器的类中,实现NestMiddleware接口来实现Nest中间件
    //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: Function) {
        console.log('Request...');
        next();
      }
    }
    
    中间件的应用
    • 使用中间件的模块必须实现NestModule接口
    • 必须使用模块类configure()方法来设置中间件
    • (此处将 LoggerMiddleware 设置在 ApplicationModule 层上)
    import { Module, NestModule, MiddlewareConsumer } form '@nestjs.common';
    import { LoggerMiddleware } from './common/middleware/logger.middleware';
    import { CatsModule } from './cats/cats.module';
    
    @Module({
      imports: [CatsModule]
    })
    export class AppModule implements NestModule {
      configure(consumer: MiddlewareConsumer) {
        consumer
          .apply(LoggerMiddleware)
          .forRoutes('cats'); //  在限定的'/cats'路由路径下的处理程序中设置了LoggerMiddleware
      }
    }
    
    • 配置中间件时将包含路由路径的对象和请求方法传递给forRoutes()方法,来限定在特定路由和请求方法下再调用中间件
    • 可以使用 async/await来实现configure()方法的异步化(例如,可以在 configure()方法体中等待异步操作的完成)
    import { Module, NestModule, RequestMethod, MiddlewareConsumer } from '@nestjs/common';
    import { LoggerMiddleware } from './common/middleware/logger.middleware';
    import { CatsModule } from './cats/cats.module';
    
    @Module({
      imports: [CatsModule],
    })
    export class AppModule implements NestModule {
      configure(consumer: MiddlewareConsumer) {
        consumer
          .apply(LoggerMiddleware)
          .forRoutes({ path: 'cats', method: RequestMethod.GET });
      }
    }
    
    • 路由同样支持模式匹配:字符?+*以及()是它们的正则表达式对应项的子集。连字符 (-) 和点 (.) 按字符串路径解析
    forRoutes({ path: 'ab*cd', method: RequestMethod.ALL });
    
    中间件消费者
    • MiddlewareConsumer 是一个帮助类,提供了几种内置方法管理中间件,各方法之间可以级联
    • forRoutes()可以接受一个/多个字符串对象,一个/多个控制器类。(大多数情况下,传递一个由逗号分隔的控制器列表)
    • apply()可使用单个/多个中间件
    • 采用exclude()可在使用某些中间件时排除某些路由,参数是一个/多个字符串,或者RouteInfo对象
    //app.module.ts - 单个控制器类(CatsController)
    import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
    import { LoggerMiddleware } from './common/middleware/logger.middleware';
    import { CatsModule } from './cats/cats.module';
    import { CatsController } from './cats/cats.controller.ts';
    
    @Module({
      imports: [CatsModule],
    })
    export class AppModule implements NestModule {
      configure(consumer: MiddlewareConsumer) {
        consumer
          .apply(LoggerMiddleware)
          .forRoutes(CatsController);
      }
    }
    
    // 对CatsController中所有注册的路由(除了exclude()标注的之外)使用中间件LoggerMiddleware
    consumer
      .apply(LoggerMiddleware)
      .exclude(
        { path: 'cats', method: RequestMethod.GET },
        { path: 'cats', method: RequestMethod.POST },
        'cats/(.*)',
      )
      .forRoutes(CatsController);
    
    函数式中间件
    • 当一个中间件,除了req,res, next之外,没有成员,没有额外的方法,没有依赖关系,那么最好简化成函数式中间件
    //中间件的定义: logger.middleware.ts
    export function logger(req, res, next) {
      console.log(`Request...`);
      next();
    };
    
    //中间件的使用: app.module.ts
    consumer
      .apply(logger)
      .forRoutes(CatsController);
    
    多个中间件
    consumer.apply(cors(), helmet(), logger).forRoutes(CatsController);
    
    全局中间件
    • 使用由INestApplication实例提供的 use()方法
      +而NestFactory.create()返回的就是一个实现 INestApplication 接口的对象:app
    const app = await NestFactory.create(AppModule);
    app.use(logger);
    await app.listen(3000);
    

    相关文章

      网友评论

          本文标题:Nest.js - Middleware

          本文链接:https://www.haomeiwen.com/subject/pdlmcktx.html