我使用内置的 NestJS ValidationPipe 以及类验证器和类转换器来验证和清理入站 JSON 正文有效负载。我面临的一种情况是入站 JSON 对象中混合使用大小写属性名称。我想在新的 TypeScript NestJS API 中纠正这些属性并将其映射到标准的驼峰式模型,这样我就不会将遗留系统中不匹配的模式耦合到我们的新 API 和新标准,本质上是使用 @Transform DTO 作为应用程序其余部分的隔离机制。例如,入站 JSON 对象的属性:
"propertyone",
"PROPERTYTWO",
"PropertyThree"
Run Code Online (Sandbox Code Playgroud)
应该映射到
"propertyOne",
"propertyTwo",
"propertyThree"
Run Code Online (Sandbox Code Playgroud)
我想使用 @Transform 来完成此任务,但我认为我的方法不正确。我想知道是否需要编写自定义 ValidationPipe。这是我目前的方法。
控制器:
"propertyone",
"PROPERTYTWO",
"PropertyThree"
Run Code Online (Sandbox Code Playgroud)
测试我模型:
"propertyOne",
"propertyTwo",
"propertyThree"
Run Code Online (Sandbox Code Playgroud)
测试我请求Dto:
import { Body, Controller, Post, UsePipes, ValidationPipe } from '@nestjs/common';
import { TestMeRequestDto } from './testmerequest.dto';
@Controller('test')
export class TestController {
constructor() {}
@Post()
@UsePipes(new ValidationPipe({ transform: true }))
async get(@Body() testMeRequestDto: TestMeRequestDto): Promise<TestMeResponseDto> {
const response = do something useful …Run Code Online (Sandbox Code Playgroud) 如何转换数据库实体User:
class User {
public firstName: string;
public lastName: string;
public phone?: string;
public email: string;
public status: EUserState;
public tokens: Token[];
public password: string;
}
Run Code Online (Sandbox Code Playgroud)
进入 DTO 实体GetUserDTO:
class GetUserDTO {
public id: number;
public firstName: string;
public lastName: string;
public phone?: string;
public email: string;
}
Run Code Online (Sandbox Code Playgroud)
在打字稿中?我正在使用@nestjs,class-validator和class-transformer包,但我没有找到任何方法来使用它们来实现这一目标。
有人可能会说,拥有 DTO 对此毫无意义,但我们在服务器和客户端之间共享 DTO 以维护 API 结构。
有任何想法吗?
我在 NodeJS 上实现的项目中使用了 class-transformer lib,但我没有找到公开实体的所有属性的方法,我尝试在类级别使用 de @Expose() decrator,但它不起作用,我希望找到类似的解决方案,因为在我的实体中一一暴露装饰器属性有点让人筋疲力尽。我想要的例子:
@Expose()
export class User{
name:string;
phone:string;
age:number
};
Run Code Online (Sandbox Code Playgroud)
目前,它仅在以下情况下有效:
export class User{
@Expose() name:string;
@Expose() phone:string;
@Expose() age:number
};
Run Code Online (Sandbox Code Playgroud) 在 NestJS 中使用和包描述 DTO 类时,有没有办法设置装饰器的执行顺序?class-validatorclass-transformer
当 的值foo设置为时,以下代码会失败null并出现错误:
需要一个字符串,但收到一个 null
@IsOptional()
@IsString()
@IsByteLength(1, 2048)
@Transform(({ value }) => validator.trim(value))
@Transform(({ value }) => validator.stripLow(value))
foo: string;
Run Code Online (Sandbox Code Playgroud)
即使我有一个isString装饰器应该检查是否确实传递了一个字符串,并且必须已经失败而不将执行传递给装饰@Transform器,但它并没有失败。
decorator typescript class-validator nestjs class-transformer
我有一个 NestJS 项目,其中同时使用类验证器和类转换器,并且我需要在类验证器抛出错误之前执行类转换器。
给定以下课程:
export class CreateProfileDto {
@IsString()
@Expose({ name: 'name' })
profileName!: string;
@IsBoolean()
@Expose({ name: 'active'})
profileActive!: boolean;
}
Run Code Online (Sandbox Code Playgroud)
我需要用属性名称而不是属性 profileName 来公开错误,其他属性也是如此。
有什么直接的想法来管理这个吗?无法要求前端向我发送具有不同名称的属性,这就是我需要调整它们的原因。
我想通过管道来做到这一点,但在错误爆发之前无法使用它。
当前错误格式:
{
"statusCode": 400,
"error": "Bad Request",
"message": [
{
"target": {
"profileName": 1
},
"value": 1,
"property": "profileName",
"children": [],
"constraints": {
"isString": "profileName must be a string"
}
}
]
}
Run Code Online (Sandbox Code Playgroud)
所需的错误格式:
{
"statusCode": 400,
"error": "Bad Request",
"message": [
{
"target": {
"name": 1
},
"value": 1,
"property": "name",
"children": …Run Code Online (Sandbox Code Playgroud) 目前我使用该class-transformer包将可选值转换为默认值
@IsString()
@IsOptional()
@Transform((description: string) => description || '')
public description: string;
Run Code Online (Sandbox Code Playgroud)
出现了两个问题。
所以基本上我想创建一个将可选值转换为默认值的函数,我当前的方法是:
function transformValueIfUndefined<TValue>(value: TValue, fallbackValue: TValue): TValue {
if (value === undefined) {
return fallbackValue;
}
return value;
}
Run Code Online (Sandbox Code Playgroud)
Transform现在我可以在装饰器中使用这个函数
@Transform((description: string) => transformValueIfUndefined(description, ''))
Run Code Online (Sandbox Code Playgroud)
但正如您所看到的,这不值得付出努力。有没有一种方法可以创建我自己的转换装饰器以及class-validator转换class-transformer可选值?
我的自定义装饰器应该是这样的
@TransformOptionalValueIfUndefined('')
Run Code Online (Sandbox Code Playgroud) 我有一个nodejs运行nestjs框架的REST API 后端,使用typeORM作为我的实体的ORM。
来自C#/Entity Framework背景,我非常习惯将我的 Dtos 映射到数据库实体。
typeORM 是否有类似的方法?
我看过automapper-ts库,但是地图声明中的那些魔法字符串看起来有点吓人......基本上,如果我能:
let user: TypeORMUserEntity = mapper.map<TypeORMUserEntity>(userDto);
Run Code Online (Sandbox Code Playgroud)
在 nodejs/typeorm 后端环境中执行此操作的方法是什么(或任何具有相同结果的替代方法)?
我正在尝试找到一种使用 DTO(使用辉煌class-validator和class-transformer库)验证主体的好方法。它工作得非常好,即使对于嵌套结构也是如此,但在我的情况下,我希望根据某些条件拥有 body 属性。
可能有助于理解的示例:
让我们想象一下我的身体应该总是有selectedCategory。根据该字段,内容可能来自类别 1,其中包含prop1OR 来自类别 2,其中包含prop2.
我不想让他们两个都为空,我真的想要么已经prop1定义要么prop2基于selectedCategory.
我认为我可以使用管道,但是如何指定要使用的正确 DTO?
我已经构建了一个“基”类,其中包含所有公共属性和一些继承自它的其他类。
我可以根据属性手动实例化管道selectedCategory,这是理想的,但我不知道将什么作为管道的第二个参数(元数据)传递。
谢谢你的帮助。
我是 NestJS 的新手,我正在尝试从查询参数中填充过滤器 DTO。
这是我所拥有的:
询问:
本地主机:3000/api/checklists?stations=114630,114666,114667,114668
控制器
@Get()
public async getChecklists(@Query(ValidationPipe) filter: ChecklistFilter): Promise<ChecklistDto[]> {
// ...
}
Run Code Online (Sandbox Code Playgroud)
DTO
export class ChecklistFilter {
@IsOptional()
@IsArray()
@IsString({ each: true })
@Type(() => String)
@Transform((value: string) => value.split(','))
stations?: string[];
// ...
}
Run Code Online (Sandbox Code Playgroud)
有了这个,类验证器不会抱怨,然而,在过滤器对象中,站实际上不是一个数组,而是一个单一的字符串。
我想将其转换为验证管道中的数组。我怎样才能做到这一点?
类转换器文档说:
隐式类型转换
注意如果您将类验证器与类转换器一起使用,您可能不想启用此功能。
为什么不?
我做了一些测试,没有发现任何问题。
实际上,情况恰恰相反:将class-transformer(带有和enableImplicitConversion=trueReflect -metadata)与class-validator结合使用似乎是一个完美的选择,并且NestJS开箱即用地支持它