routing-controllers icon indicating copy to clipboard operation
routing-controllers copied to clipboard

question: how to auto-transform body instance to plain in routing-controllers

Open ermal-abiti opened this issue 1 year ago • 5 comments

I have this following code:

@JsonController('/auth')
@Service()
export class AuthController {
    constructor(private readonly authService: AuthService) {}

    @Post('/register')
    @HttpCode(201)
    @Serialize(UserDto)
    async registerUser (@Body() body: RegisterDto) {
        console.log(body)
        return this.authService.register(body.toJson());
    }
}

As you can see the controller is using validation. After I call the api endpoint, the console outputs RegisterDto { username: 'test', password: 'test' }.

Coming from a nestjs perspective, it would automatically convert this dto instance to a plain object, and the console would output this { username: 'ermal1', password: 'dasd' }.

How can i achieve this using routing-controllers ?

ermal-abiti avatar May 03 '23 10:05 ermal-abiti

@ermal-abiti you can disable class transformation in either the global settings of routing-controller or per parameter basis. Please take a look at the documentation and search for class-transformer

attilaorosz avatar May 03 '23 10:05 attilaorosz

@attilaorosz attilaorosz I disabled:

useExpressServer(app, {
	routePrefix: '/api',
    validation: {
        whitelist: true,
    },
	controllers: [AuthController],
	defaultErrorHandler: true,
    classTransformer: false,
});

But now it is not validating the body and it is not applying the whitelist: true at validation options.

DTO:

export class RegisterDto {
    @IsString()
    username: string;

    @IsString()
    password: string;
}

And I am sending this json request body:

{
 "username":"test",
"password:"test"
"name": "test"
}

And the console is outputing this: { username: 'test', password: 'test', name: 'test' }

Also if i remove one of the fields and i send this json for ex: {"username": "test"}, it skips the validation part, so it doesn't throw an error or something. Shouldn't it validate based on the DTO ?

ermal-abiti avatar May 03 '23 11:05 ermal-abiti

Any solution for this ?

ermal-abiti avatar May 18 '23 10:05 ermal-abiti

Sorry for the late reply, do you happen to have a repro repo for this? I have no idea what @Serialize() does in your example.

attilaorosz avatar Jun 11 '23 17:06 attilaorosz

@attilaorosz @Serialize() does not have to do with this. I have

// index.js
...
useExpressServer(app, {
	routePrefix: '/api',
    validation: {
        whitelist: true,
    },
	controllers: [AuthController],
	defaultErrorHandler: true,
    classTransformer: true,
});
...

// auth.controller.ts
@JsonController('/auth')
@Service()
export class AuthController {
    constructor(private readonly authService: AuthService) {}

    @Post('/register')
    @HttpCode(201)
    async registerUser (@Body() body: RegisterDto) {
        console.log(body)
        return this.authService.register(body);
    }
}

The problem is at body in /register route. I want body to a be plain object after validation, for example { username: 'test', password: 'test' }. But by default body after validation comes as RegisterDto { username: 'test', password: 'test' } (instance of RegisterDto). Otherwise if I set classTransformer: false, the body comes as plain object but it does not go through the validation process. What i want to achieve is validate the body and return it after validation as plain object { username: 'ermal1', password: 'dasd' }. Is there any specific option for this ? Thanks for your response

ermal-abiti avatar Jul 27 '23 08:07 ermal-abiti