DTO不适用于微服务,但直接用于api

时间:2019-07-04 14:18:41

标签: microservices nestjs class-validator

我正在用nestJS开发API和微服务, 这是我的控制器功能

    @Post()
    @MessagePattern({ service: TRANSACTION_SERVICE, msg: 'create' })
    create( @Body() createTransactionDto: TransactionDto_create ) : Promise<Transaction>{
        return this.transactionsService.create(createTransactionDto)
    }

当我调用post api时,dto验证可以正常工作,但是当我使用微服务验证调用此方法时,它无法正常工作,并且可以传递给服务而不会因错误而拒绝。 这是我的DTO

import { IsEmail, IsNotEmpty, IsString } from 'class-validator';
export class TransactionDto_create{
    @IsNotEmpty()
    action: string;

    // @IsString()
    readonly rec_id : string;

    @IsNotEmpty()
    readonly data : Object;

    extras : Object;
    // readonly extras2 : Object;
}

当我不带操作参数的情况下调用api时,它显示需要执行错误操作,但是当我从微服务中使用

进行调用时
  

const pattern = {service:TRANSACTION_SERVICE,msg:'create'};       const data = {id:'5d1de5d787db515190190ccb2',其他:{'asdf':'dsf'}};

return this.client.send<number>(pattern, data)
     

它不会引发错误并可以使用。   我还添加了globalpipe验证。

app.useGlobalPipes(new ValidationPipe({
    disableErrorMessages: false,  // set true to hide detailed error message
    whitelist: false,  // set true to strip params which are not in DTO
    transform: false // set true if you want DTO to convert params to DTO class by default its false
  }));

它如何同时适用于api和微服务,因为我需要将所有功能集中在一处并且具有相同的功能,以便可以根据客户端对其进行调用。

2 个答案:

答案 0 :(得分:0)

我要弯腰,假设main.ts中有app.useGlobalPipes(new ValidationPipe());行。 From the documentation

  

对于混合应用useGlobalPipes()方法未设置网关和微服务的管道。对于“标准”(非混合)微服务应用程序,useGlobalPipes()确实在全局安装管道。

您可以改为从AppModule全局绑定管道,也可以在需要通过@UsePipes()进行验证的每条路由上使用ValidationPipe装饰器

More info on binding pipes here

答案 1 :(得分:0)

ValidationPipe引发HTTP BadRequestException,而代理客户端期望RpcException。

@Catch(HttpException)
export class RpcValidationFilter implements ExceptionFilter {
    catch(exception: HttpException, host: ArgumentsHost) {
        return new RpcException(exception.getResponse())
    }
}
@UseFilters(new RpcValidationFilter())
@MessagePattern('validate')
async validate(
    @Payload(new ValidationPipe({ whitelist: true })) payload: SomeDTO,
) {
    // payload validates to SomeDto 
    . . .
}