Skip to content
On this page

AOP架构

在某个过程前后,执行一段统一逻辑

  • axios的拦截器
  • express的洋葱模型

而 Nest 实现 AOP 的方式更多,一共有五种,包括 Middleware、Guard、Pipe、Interceptor、ExceptionFilter:、 Alt text

中间件 Middleware

模块/路由中间件

ts
import { Module, NestModule, 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('cats');
  }
}

全局中间件

ts
const app = await NestFactory.create(AppModule);
app.use(logger);
await app.listen(3000);

路由守卫 Guard

Guard 是路由守卫的意思,可以用于在调用某个 Controller 之前判断权限,返回 true 或者 false 来决定是否放行:

  • @UseGuards(AuthGuard)
  • app.useGlobalGuards(new AuthGuard())
ts
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    const request = context.switchToHttp().getRequest();
    return validateRequest(request);
  }
}
ts
@UseGuards(AuthGuard)
@Controller()
export class AppController {}

Interceptor拦截器

Interceptor 是拦截器的意思,可以在目标 Controller 方法前后加入一些逻辑:

  • @UseInterceptor(AuthInterceptor)
  • app.useGlobalInterceptor(new AuthInterceptor())

Alt text

Pipe

Pipe 是管道的意思,用来对参数做一些检验和转换:

同上,也是一个实现了管道接口的类,通过usePipes修饰器局部启用,或者在app.useGlobalPipes全局启用

  • @UsePipes(AuthPipes)
  • app.useGlobalPipes(new AuthPipes())

ExceptionFilter

  • @UseFilter(ExceptionFilter)
  • app.useGlobalFilter(new ExceptionFilter())

总结

Alt text Nest 基于 express 这种 http 平台做了一层封装,应用了 MVC、IOC、AOP 等架构思想。

MVC 就是 Model、View Controller 的划分,请求先经过 Controller,然后调用 Model 层的 Service、Repository 完成业务逻辑,最后返回对应的 View。

IOC 是指 Nest 会自动扫描带有 @Controller、@Injectable 装饰器的类,创建它们的对象,并根据依赖关系自动注入它依赖的对象,免去了手动创建和组装对象的麻烦。

AOP 则是把通用逻辑抽离出来,通过切面的方式添加到某个地方,可以复用和动态增删切面逻辑。

Nest 的 Middleware、Guard、Interceptor、Pipe、ExceptionFilter 都是 AOP 思想的实现,只不过是不同位置的切面,它们都可以灵活的作用在某个路由或者全部路由,这就是 AOP 的优势。

我们通过源码来看了它们的调用顺序,Middleware 是 Express 的概念,在最外层,到了某个路由之后,会先调用 Guard,Guard 用于判断路由有没有权限访问,然后会调用 Interceptor,对 Contoller 前后扩展一些逻辑,在到达目标 Controller 之前,还会调用 Pipe 来对参数做检验和转换。所有的 HttpException 的异常都会被 ExceptionFilter 处理,返回不同的响应。