Nodejs 请教一个 nestjs 创建 updateDto 的问题
Nodejs 请教一个 nestjs 创建 updateDto 的问题
大家好,请教一个关于 ‘class-validator’ 和 PartialType 的问题:
在用 ‘@nestjs/swagger’ 的 PartialType 创建 updateDto 时,我发现了一个问题,PartialType 会为 createDto 里的每个属性添加 @IsOptional() 修饰器,导致前端传入的所有值为 null 的属性都能跳过 ‘class-validator’ 的验证,顺利通过 ValidationPipe
而 undefined 和 null 对于 ORM ,例如 typeorm 有不同的含义,例如:
usersRepository.update({ name: null }) 表示将字段 name 更新为 null
usersRepository.update({ name: undefined }) 表示不对字段 name 进行更新
最终本该 not null 的字段接受了一个 null 值,导致数据库抛错 NOT NULL constraint failed
这应该是一个常见的应用场景吧?没人遇到类似的问题吗?
https://stackoverflow.com/questions/70380391/how-to-mark-certain-fields-as-nullable-or-not-nullable-in-nestjs-request-validat
https://stackoverflow.com/questions/68622366/nestjs-update-is-returning-null-for-other-fields-thereby-giving-validation-issue
附上测试代码,是我实现的方式不对吗?我在网上都搜不到这个问题
https://github.com/yodhcn/mapped-types-example
可以重写属性添加修饰器
export class UpdateUserDto extends PartialType(CreateUserDto) {
()
()
name?: string;
}
#1 是的,可以重写,但如果我多数字段都是 NOT NULL 的活,我也只能将每个字段手动重写,PartialType 失去了它的存在意义,这是否意味着 PartialType 设计的不合理?
参考 https://github.com/typestack/class-validator/issues/579
应该重写成 ((object, value) => value !== undefined)
也不好说是 PartialType 不好,更多可能是 ()的问题
而且这个问题在 class-validator 的 issues 里讨论的更多
在你的 update 或者 create 里加上 || ‘’ ?
不从 dto 直接更新数据库
我觉得是这样的,而且也不应该放在 /swagger 包下
在 NestJS 中,创建 updateDto
(数据传输对象)是一个常见的任务,通常用于更新实体时接收部分或全部字段的数据。updateDto
通常包含可选字段,以允许部分更新。以下是如何创建一个简单的 updateDto
的示例。
假设我们有一个 User
实体,其结构如下:
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
email: string;
// 其他字段...
}
为了创建一个 UpdateUserDto
,我们可以这样做:
import { PartialType } from '@nestjs/mapped-types';
import { CreateUserDto } from './create-user.dto'; // 假设已有一个创建用户的Dto
export class UpdateUserDto extends PartialType(CreateUserDto) {}
这里我们使用了 @nestjs/mapped-types
包中的 PartialType
,它会将 CreateUserDto
中的所有字段变为可选字段。如果 CreateUserDto
如下:
import { IsString, IsEmail } from 'class-validator';
export class CreateUserDto {
@IsString()
readonly name: string;
@IsEmail()
readonly email: string;
// 其他字段及其验证器...
}
那么 UpdateUserDto
将自动继承 CreateUserDto
的结构,但所有字段都会变成可选的,非常适合用于更新操作。
这种方式不仅减少了重复代码,还保证了 updateDto
和 createDto
之间的一致性。