我使用NodeJ / NestJs构建RESTful服务。我创建了一些与请求JSON相匹配的对象。这些对象中有一些可选属性,但是如果客户端不通过JSON发送默认值,我想为它们设置默认值。
达到目标的最佳方法是什么?
这是我与JSON匹配的DTO。
import { IsDefined, IsNumber, Min } from 'class-validator';
import { ApiModelProperty, ApiModelPropertyOptional } from '@nestjs/swagger';
export class RequestDto {
@IsDefined()
@IsNumber()
@Min(0)
@ApiModelProperty({description: 'The current age.'})
public CurrentAge: number;
@ApiModelPropertyOptional({description: 'The existing saving amount.'})
public ExistingSavingAmount: number = 0;
}
这是我的NestJs控制器
import { Controller, Post, Body, Param } from '@nestjs/common';
import { RequestDto } from './Dto/Request.Dto';
import { ApiResponse, ApiOperation } from '@nestjs/swagger';
@Controller('mycontroller')
export class MyController {
@Post('MyEndPoint')
@ApiOperation({ title: 'Do something' })
@ApiResponse({ status: 201, description: 'Something is done' })
public doSomething(@Body() request: RequestDto) {
// do more jobs
}
}
我启动该服务,并将以下JSON发布到我的终点
{
"CurrentAge": 40,
}
在我的控制器中,我看到ExistingSavingAmount
为空,而不是值为0。但是,如果直接实例化RequestDto
,则可以看到ExistingSavingAmount
的值为0。 >
答案 0 :(得分:4)
仅当RequestDto
实际上被实例化为类时,您的默认值才适用。由于您已经在使用class-validator进行验证,因此可以使用classTransformer.plainToClass()
来实例化该类。
如果您使用内置的ValidationPipe
,则可以使用{ transform: true }
选项来自动实例化RequestDto
类:
@UsePipes(new ValidationPipe({ transform: true }))
@Post('MyEndPoint')
public doSomething(@Body() request: RequestDto) {
或作为全局管道:
async function bootstrap() {
const app = await NestFactory.create(ApplicationModule);
app.useGlobalPipes(new ValidationPipe({ transform: true }));
await app.listen(3000);
}
bootstrap();
答案 1 :(得分:1)
好的,没有OP的代码样本,此响应的保真度可能需要改进。就是说,“ nest-y”方式是通过TransformPipe实现的。
他们给出的规范示例是针对ParseIntPipe的:
import { Injectable, BadRequestException} from '@nestjs/common';
@Injectable()
export class ParseIntPipe {
transform(value, metadata) {
const val = parseInt(value, 10);
if (isNaN(val)) {
throw new BadRequestException('Validation failed');
}
return val;
}
}
在不知道您的默认值是什么样的情况下,我将假设它像是一种产品,并且您想要默认一些内容并将某些内容作为空字符串输入
import { Injectable, BadRequestException} from '@nestjs/common';
// we will assume you have your own validation for the non-optional bits
const optionalDefaults = {
description: '',
category: 'Miscelleneous'
}
@Injectable()
export class ProductDefaultsPipe {
transform(value, metadata) {
const val = Object.assign(optionalDefaults, value);
return val;
}
}
现在,这表示您可能正在使用提供架构和模型定义的工具(例如Joi或Mongoose)。如果您愿意,那么我建议您在该架构中设置所有默认值和验证,然后在您的TransformPipe中应用该架构,而不要编写太多自定义代码。例如,如果您有一个ProductSchema,它将为您工作:
@Injectable()
export class ProductDefaultsPipe {
async transform(value, metadata) {
const val = new Product(value);
const isValid = await val.validate();
if (!isValid) {
throw new BadRequestException('Validation failed');
}
return val;
}
}