nest的核心概念

 请求进来 --- 中间件 --- 守卫 --- 拦截器 --- 通道 --- 处理(controller层) --- 拦截器 --- 返回

handler定义:  就是被砸咱们自己写的 controller层 service层代码处理的阶段

Pipe :  就是实现 PipeTransform 接口的 transform 方法,它的返回值就是传给 handler 的值 (controller层)。

useGlobalInterceptors: 拦截器

举个例子 

// 使用全局通道 

app.useGlobalPipes(new ValidationPipe()); 

 // 这个拦截器可以在 handler 前面处理 request进来的 数据体, 也可以作用在 handler层后 面,处理 handler 之后的返回的 数据体

  app.useGlobalInterceptors(new FormatResponseInterceptor());  使用全局拦截器

-----------------------------------------

  • DTO(Data Transfer Object):数据传输对象,Service 或 Manager 向外传输的对象。

  • VO(View Object):显示层对象,通常是 Web 向模板渲染引擎层传输的对象。

-------------------------------------------

Nest框架内部是如何做到把TypeScript的类型定义变成功能实现?

Nest框架是一个基于Node.js的框架,它使用了TypeScript来提供强类型支持,并将类型定义与代码编译紧密结合。

TypeScript是一种静态类型检查的编程语言,它通过类型注解来在编译阶段检查代码的正确性。在Nest框架中,类型定义不仅仅是用来作为类型约束,还可以通过装饰器等方式对代码进行元编程,从而实现一些功能。

Nest框架使用了装饰器来定义控制器、提供者、中间件等组件,这些装饰器使用了TypeScript的类型系统来进行静态类型检查。在编译过程中,这些装饰器会被解析,并根据类型定义生成对应的代码。这意味着类型定义可以影响最终编译后的代码。

掘金小册  

 具体实现原理可以看这个章节。 

-------------------------

下面简单对章节进行总结: 

不知道大家有没有感觉很神奇,只是通过装饰器声明了一下,然后启动 Nest 应用,这时候对象就给创建好了,依赖也给注入了。

那它是怎么实现的呢?

Nest 的实现原理就是通过装饰器给 class 或者对象添加元数据,然后初始化的时候取出这些元数据,进行依赖的分析,然后创建对应的实例对象就可以了。

所以说,nest 实现的核心就是 Reflect metadata 的 api。

关于TypeScript部分,为什么跟Nest框架结合可以实现代码的功能改变,既元编程

其实还有一个疑问,依赖的扫描可以通过 metadata 数据,但是创建的对象需要知道构造器的参数,现在并没有添加这部分 metadata 数据呀:

这就不得不提到 TypeScript 的优势了,TypeScript 支持编译时自动添加一些 metadata 数据:

import "reflect-metadata";
 
class Guang {
  @Reflect.metadata("名字", "光光")
  public say(a: number): string {
    return '加油鸭';
  }
}

按理说我们只添加了一个元数据,生成的代码也确实是这样的:

但是呢,ts 有一个编译选项叫做 emitDecoratorMetadata,开启它就会自动添加一些元数据。

开启之后再试一下:

所以说,只要开启了这个编译选项,ts 生成的代码会自动添加一些元数据。

然后创建对象的时候就可以通过 design:paramtypes 来拿到构造器参数的类型了,那不就知道怎么注入依赖了么?

所以,nest 源码里你会看到这样的代码:

这也是为什么 nest 会用 ts 来写,因为它很依赖这个 emitDecoratorMetadata 的编译选项。

你用 cli 生成的代码模版里也都默认开启了这个编译选项:

-----

这就是 nest 的核心实现原理:通过装饰器给 class 或者对象添加 metadata,并且开启 ts 的 emitDecoratorMetadata 来自动添加类型相关的 metadata,然后运行的时候通过这些元数据来实现依赖的扫描,对象的创建等等功能。

Nest 的装饰器都是依赖 reflect-metadata 实现的,而且还提供了一个 @SetMetadata 的装饰器让我们可以给 class、method 添加一些 metadata

---

Nest 的装饰器的实现原理就是 Reflect.getMetadata、Reflect.defineMetadata 这些 api。通过在 class、method 上添加 metadata,然后扫描到它的时候取出 metadata 来做相应的处理来完成各种功能。

Nest 的 Controller、Module、Service 等等所有的装饰器都是通过 Reflect.meatdata 给类或对象添加元数据的,然后初始化的时候取出来做依赖的扫描,实例化后放到 IOC 容器里。

实例化对象还需要构造器参数的类型,这个开启 ts 的 emitDecoratorMetadata 的编译选项之后, ts 就会自动添加一些元数据,也就是 design:type、design:paramtypes、design:returntype 这三个,分别代表被装饰的目标的类型、参数的类型、返回值的类型。

当然,reflect metadata 的 api 还在草案阶段,需要引入 reflect metadata 的包做 polyfill。

Nest 还提供了 @SetMetadata 的装饰器,可以在 controller 的 class 和 method 上添加 metadata,然后在 interceptor 和 guard 里通过 reflector 的 api 取出来。

理解了 metadata,nest 的实现原理就很容易搞懂了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值