【Nestjs学习日记】DTO

作者:markzzw 时间:2024-1-31

线上代码:CodeSandbox

Github:zhangzewei/nest-learning-tutorial
系列阅读

  1. 【Nestjs学习日记】初识nestjs
  2. 【Nestjs学习日记】Nest Controller
  3. 【Nestjs学习日记】抛出异常
  4. 【Nestjs学习日记】Module

在NestJS应用程序开发中,DTO(Data Transfer Object)是一个重要的概念。DTO用于在不同的层之间传输数据,并且在实现松耦合和数据验证方面发挥了关键的作用。在本篇【NestJS学习日记】中,我们将深入探讨DTO的概念和在NestJS应用程序中的应用。

在现代的应用程序开发中,经常会涉及到在不同的层之间传输数据。例如,从客户端发送的数据需要在服务器端进行处理和验证,然后可能会传递给数据库或其他外部服务。在这个过程中,数据的结构和格式可能会有所不同,这就是DTO的用武之地。

DTO是一种用于定义数据传输的对象,它定义了传输的数据的结构和字段。通过使用DTO,我们可以明确指定在不同层之间传输的数据的内容,确保数据的一致性和有效性。DTO还可以用于数据验证,以确保传输的数据符合预期的格式和规范。

在本篇【NestJS学习日记】中,我们将学习如何创建和使用DTO。我们将了解如何定义DTO类,如何在NestJS的控制器和服务中使用DTO,并且如何进行数据验证和转换。我们还将研究DTO的最佳实践和常见的使用场景。

通过理解和掌握DTO的概念和应用,我们将能够更好地组织和管理数据传输,在不同的层之间实现松耦合和有效的数据交互。DTO是NestJS应用程序开发中的重要概念,它能够提高代码的可读性、可维护性和可扩展性。

在接下来的文章中,让我们一起深入研究DTO的概念和应用,掌握在NestJS应用程序中使用DTO的技巧和技巧!

前期准备

这里需要先安装依赖

kotlin 复制代码
npm install class-validator
npm install class-transformer
npm install @nestjs/mapped-types

创建 DTO

在对应的 Module 目录下新建目录 'dto/',然后新建 dto 文件,以 cat module 为例,新建 'cat.dto.ts' 文件,然后在文件内部新增两个 dto 类。

ts 复制代码
export class CreateCatDto {
  name: string;
  age: number;
}

export class UpdateCatDto {
  name?: string;
  age?: number;
}

使用 DTO

Nestjs 是使用 Typescript 进行编写的,所以我们可以将这两个 dto 为 Controller 中的方法进行参数的类型描述。

cat.controller.ts

ts 复制代码
import { Controller, Body, Post, Param, Put } from '@nestjs/common';
import { CreateCatDto, UpdateCatDto } from './dto/cat.dto';

@Controller('cat')
export class CatController {
  @Post()
  createCat(@Body() body: CreateCatDto) {
    return body;
  }

  @Put(':id')
  updateCat(@Param('id') id: string, @Body() body: UpdateCatDto) {
    return { id, body };
  }
}

使用 DTO 对参数校验

DTO 不仅仅是对参数进行类型描述,还可以对请求的参数进行类型校验,首先我们需要增加一个全局的校验 pipe。

app.module.ts

ts 复制代码
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe()); // 新增校验 pipe
  await app.listen(3000);
}
bootstrap();

接下改变一下我们的 dto, 这里需要使用到 class-validator 提供的装饰器修饰 dto 类的属性。

ts 复制代码
import { IsString, IsNumber } from 'class-validator';

export class CreateCatDto {
  @IsString()
  name: string;
  @IsNumber()
  age: number;
}

此时我们尝试 post 请求:

  1. 不传入任何参数,返回了一个错误信息,告诉我们参数的要求。
  2. 传入 name 和 age,但是 age 给一个 string,此时只返回了对于 age 参数的描述。

这就是使用 dto 对参数进行校验的方法。

继承

可以看出 CreateDto 和 UpdateDto 是相似的,所以可以使用继承的方式,但是 UpdateCatDto 的属性是可选的,这就要使用 @nestjs/mapped-types 的 PartialType。

ts 复制代码
import { IsString, IsNumber } from 'class-validator';
import { PartialType } from '@nestjs/mapped-types';

export class CreateCatDto {
  @IsString()
  name: string;
  @IsNumber()
  age: number;
}

export class UpdateCatDto extends PartialType(CreateCatDto) {}

此时尝试 put 请求:

  1. 发出 name 和 age,没有报错。
  2. 只发出 name,没有报错。
  3. 只发出 age,但是是 string,报错 age 需要是数字类型。 可以看到 UpdateCatDto 即继承了 CreateDto 的校验,但是也有自身的可选类型描述。

总结

DTO 不仅可以帮助我们进行类型描述,还可以对 body 进行校验,并且通过继承可以把类似的类型组合起来,也不会失去校验的功能。

相关推荐
羲云几秒前
AI 分站搭完就能发链接?上线前先过这 5 关
前端
葡萄城技术团队4 分钟前
一个 F4 快捷键,为什么能决定 Web 表格是否像 Excel?
前端
王川7089 分钟前
商协会后台前端的模块聚合实践
前端·后端
jerrywus10 分钟前
Codex、Claude Code、DSH 怎么用手机管?我试了试 Agents Anywhere
前端·claude·deepseek
twj_50217 分钟前
农业商业计划书PPT制作完全指南
前端
门思科技18 分钟前
ThinkLink Edge 本地部署实战:数据不出厂区,从硬件选型到与云端双向迁移
前端
花涧鹤28 分钟前
学完分支和循环一脸茫然?我写了个扫雷,把它们全串起来了
前端
fanruitian1 小时前
python 进程 线程
java·前端·python
ZoeLandia1 小时前
React03:useState 与不可变更新
前端·react.js·typescript·react