简体   繁体   English

NestJS 中的 class 变压器 DTO 如何在运行时应用?

[英]How is the class transformer DTO in NestJS being applied at runtime?

I'm messing around with NestJS and class-validators for the first time.我第一次弄乱了 NestJS 和类验证器。 In that context I met something I didn't quite understand, and haven't been able to find an explanation online.在那种情况下,我遇到了一些我不太理解的东西,并且无法在网上找到解释。

I'm struggling to understand how exactly the library understands my DTO and what is valid and what is not due to the fact the DTO is ONLY being used as a type.我正在努力理解图书馆究竟是如何理解我的 DTO 以及什么是有效的,什么是无效的,因为 DTO 仅用作一种类型。 How exactly does this work?这究竟是如何工作的?

Here is is an example DTO:这是一个示例 DTO:

export class LoginDto {
  @IsEmail()
  email: string;

  @IsString()
  password: string;
}

Here is an example in NestJS where I validate the body based on the DTO:这是 NestJS 中的一个示例,我根据 DTO 验证正文:

  @Post('login')
  login(@Body() body: LoginDto) {
    return this.authService.login(body);
  }

So just to reiterate my question one more time.因此,再次重申我的问题。 How is the body being validated against the DTO when it's only declared as a TYPE, which surely doesn't have anything to do with runtime, right?当仅将主体声明为 TYPE 时,如何针对 DTO 验证主体,这肯定与运行时没有任何关系,对吧? Right?正确的?

Thanks in advance:)提前致谢:)

So NestJS by default makes use of Typescript metadata emitted from decorators and the libraries class-transformer (abv. ct) and class-validator (abv. cv) for the body validation via the ValidaitonPipe .因此,NestJS 默认使用装饰器发出的 Typescript 元数据以及库class-transformer器(abv.ct)和class-validator (abv.cv)通过ValidaitonPipe进行主体验证。 On compilation, Typescript will emit some metadata about the code, what parameters are in a method, if they have a class type, what metadata should be attached to them ( designtype:params , req.body , etc), and other useful data that Nest or ct / cv reads at runtime.在编译时,Typescript 将发出一些关于代码的元数据,方法中有哪些参数,如果它们具有 class 类型,应该附加哪些元数据( designtype:paramsreq.body等),以及其他有用的数据Nest 或ct / cv在运行时读取。 Nest uses some of this metadata to pass on proper values to the pipe, like what class type is set for a decorator (like your LoginDto ) and what part of the request the value comes from (this is determined by @Body() / @Query() / @Param() /etc) and these are passed to the pipe in the second parameter of the transform() method under ArgumentMetadata . Nest 使用其中一些元数据将正确的值传递给 pipe,例如为装饰器设置的 class 类型(如您的LoginDto )以及该值来自请求的哪一部分(这由@Body() / @Query()确定@Query() / @Param() /etc) 并将这些传递给ArgumentMetadatatransform()方法的第二个参数中的 pipe。 Then, the class type is passed on to ct so that plainToInstance(ClassType, value) can be called to make a class instance of the LoginDto and then cv 's validate is called to validate that each parameter of the instance properly matches the @IsWhatever() decorators that are assigned to the property.然后,将 class 类型传递给ct以便可以调用plainToInstance(ClassType, value)来生成 LoginDto 的LoginDto实例,然后调用cvvalidate来验证实例的每个参数是否正确匹配@IsWhatever()分配给属性的装饰器。 Really interesting stuff.真的很有趣的东西。

I highly suggest you take a look at the emitted compiled JavaScript after running your build command to get a better idea of what is being emitted and thus read at runtime我强烈建议您在运行build命令后查看已发出的编译 JavaScript 以更好地了解正在发出的内容,从而在运行时读取

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM