😎😎😎基于AOP和IoC架构的Nest,想有多好玩就有多好玩!!!

NestJs 是一个非常优秀的 Node 的后端框架,它的底层使用的是 expressNode HTTP 框架,它提供了 express 没有的 MVCIoCAOP 等架构特性,使得代码更容易维护、扩展。

NestJs 受到 Angular 的启发,在服务端提供一个开箱即用的应用框架,让开发人员和团队能够创造出高可测试、可扩展、松耦合、易维护的应用。代码组织更规范,只有代码规范了,开发出的应用才可以易测试、可扩展、松耦合、易维护。

AOP

AOP 的中文全称为 Aspect Oriented Programming,翻译成人话就是 面向切面编程,那么什么是切面呢?

其实你可以理解为一个汉堡,它的本质就是一个面包,在这里我们把它理解为我们的应用程序,我们要在扩展这个应用程序的时候,需要在里面添加更多的代码,而这个过程就是向这个面包加馅的过程,如下图所示,不知道你饿了没:

😎😎😎基于AOP和IoC架构的Nest,想有多好玩就有多好玩!!!

AOP 主要有以下的特点:

  • 扩展功能方便,不影响业务之间的逻辑;
  • 逻辑集中处理;
  • 更有利于代码复用;

那我们再回到 NestJs 中的 AOP,在 Nest 中实现 AOP 的方式有很多,具体如下图所示:

😎😎😎基于AOP和IoC架构的Nest,想有多好玩就有多好玩!!!

我们在前端发送一个请求,它首先会经过 Controller(控制器)、Services(服务)、Repository(数据接入)的逻辑,主要流程如下图所示:

😎😎😎基于AOP和IoC架构的Nest,想有多好玩就有多好玩!!!

如果你想在这个调用链路里加入一些通用逻辑,你可以在这个执行流程中加入不同的逻辑,这个就是 AOP 给我们带来的好处,例如你要添加一些异常处理,日志记录。

Nest生命周期

vuereact 中都有它自己的生命周期,在 NestJs 中也有,它的整个生命周期如下图所示:

😎😎😎基于AOP和IoC架构的Nest,想有多好玩就有多好玩!!!

每个生命周期阶段都有不同的逻辑,例如 Interceptors(拦截器),它分为前置拦截器和后置拦截器,前置拦截器又有这么三个逻辑,它们分别是全局拦截器控制器拦截器路由拦截器三个。

一个完整的生命周期主要是有以下步骤:

  1. 收到请求;
  2. 全局中间件;
  3. 模块中间件;
  4. 全局守卫;
  5. 控制器守卫;
  6. 路由守卫;
  7. 全局拦截器(控制器之前);
  8. 控制器层拦截器(控制器之前);
  9. 路由拦截器(控制器之前);
  10. 全局管道;
  11. 控制器管道;
  12. 路由管道;
  13. 路由参数管道;
  14. 控制器;
  15. 路由拦截器;
  16. 控制器拦截器;
  17. 全局拦截器;
  18. 路由过滤器;
  19. 控制器过滤器;
  20. 全局过滤器;
  21. 服务器响应;

AOP应用案例之MIddleware (中间件)

中间件是一个在路由处理器之前被调用的函数,中间件函数可以访问请求和响应对象,以及应用程序的 请求-响应 周期中的 next() 中间件函数,下一个中间件函数通常由名为next的变量表示。

通俗的讲,中间件就是匹配路由之前或者匹配路由完成做的一系列的操作。

😎😎😎基于AOP和IoC架构的Nest,想有多好玩就有多好玩!!!

NestJs 的中间件实际上等价于 express 中间件,中间件函数主要执行的以下任务:

  • 执行任何代码;
  • 对请求和响应对象进行更改;
  • 结束 请求-响应 周期;
  • 调用堆栈中的下一个中间件函数;
  • 如果当前的中间件函数没有结束 请求-响应 周期,它必须调用 next() 将控制传递给下一个中间件函数,否则请求将被挂起;

NestJs 中,它既可以是一个函数,也可以是一个被 @Injectable() 装饰的类,如果使用的是类,则必须 implement NestMiddleware 接口。

创建中间件

要想创建中间件,NestJs 官方脚手架给我们提供了创建中间件的命令,如下所示:

nest g middleware middleware/wao

最后面那个参数是路径和文件名称,最终生成的代码(代码修改过)和文件如下所示:

😎😎😎基于AOP和IoC架构的Nest,想有多好玩就有多好玩!!!

引入

创建好中间件之后要在全局模块下引入,也就是 app.module.ts 文件下引入:

import { WaoMiddleware } from './middleware/wao/wao.middleware';

并且将 app.module.ts 文件下的 AppModule 类进行修改,具体代码如下所示:

export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(WaoMiddleware).forRoutes('niubi'); // 匹配牛逼路由
  }
}

我们在 app.controller.ts 文件下编写以下代码,如下所示:

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller('niubi')
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return '你小子你终于来了,等你好久了';
  }
}

此时当我们在浏览器输入完整地址时,并且请求地址为 niubi 路由时,会经过中间件,具体如下图所示:

😎😎😎基于AOP和IoC架构的Nest,想有多好玩就有多好玩!!!

😎😎😎基于AOP和IoC架构的Nest,想有多好玩就有多好玩!!!

当前这个配置访问其他路由时不会经过该中间件。

如果没有调用 next() 方法,并且没有调用 res.send() 方法,该请求会被挂起,这个浏览器页面会不停的转圈圈,如下图所示:

😎😎😎基于AOP和IoC架构的Nest,想有多好玩就有多好玩!!!

但你调用 res.send() 表示会对该请求进行了拦截,例如该用户没有权限访问该路由:

import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

@Injectable()
export class WaoMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    res.send('<h1>你小子我忍你好久了,不给你访问</h1>');
  }
}

😎😎😎基于AOP和IoC架构的Nest,想有多好玩就有多好玩!!!

到这里文章也就结束了,更多详细的例子可以查看官方文档,写得挺好的。

总结

NestJs 底层是基于 express 封装的框架,主要是应用了 IoCAOP 等架构思想,如果你了解 Typescript,并且如果你有 express 基础的话,随便看两眼文档就可以上手了,真的很好玩,强烈推荐。

NestJs 我从去年年初就想学了,到现在才有机会学,这么好用也难怪我会这么喜欢!!!

本文正在参加「金石计划」

原文链接:https://juejin.cn/post/7222189908428783653 作者:Moment

(0)
上一篇 2023年4月16日 上午10:51
下一篇 2023年4月16日 上午11:02

相关推荐

发表回复

登录后才能评论