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

@Body is not parsed to Request Body schema

Open Robstaa opened this issue 3 years ago • 4 comments

Hi! I am using the @Body decorator from routing-controllers and it somehow doesn't parse to the Swagger Docs. I read that it might have to do with using @Body and not Request Body, but routing-controllers does not seem to support any Request Body Decorator.

The response is parsed correctly though!

export type SignUpBody = {
    email: string;
    password: string;
    userType: UserType;
};

@JsonController('/auth/')
export class AuthenticationController {
    @OpenAPI({
        summary: 'User sign up for buyer and supplier owners',
        description: 'Input value of `userType` can be either `supplier` or `buyer`',
        requestBody: {
            required: true,
            content: {
                'application/json': {
                    example: {
                        email: '[email protected]',
                        password: '1234!hello@',
                        userType: 'admin',
                    },
                },
            },
        },
        responses: {
            401: {
                description:
                    'Invalid password. Password must be at least 8 characters long, have at least one uppercase letter, one lowercase letter, one number, and one special character.',
            },
            409: {
                description: 'User already exists',
            },
            422: {
                description: 'Invalid access type',
            },
            500: {
                description: 'Internal server error',
            },
        },
    })
    @HttpCode(201)
    @ResponseSchema(User)
    @Post('sign-up')
    async signUp(@Body() body: SignUpBody): Promise<User> {
        return signUp(body);
    }
}

Any ideas how I can also parse the Body to the schema in the Swagger docs? Thanks a lot!

Robstaa avatar Apr 22 '22 11:04 Robstaa

Try converting type to class or interface?

arpitBhalla avatar Jun 23 '22 12:06 arpitBhalla

Same problem, I use Interfaces

kKen94 avatar Jul 04 '23 10:07 kKen94

I used class-validator library

import {
    IsArray,
    IsEmail,
    IsNumber,
    IsObject,
    IsString,
    Length,
    ValidateNested,
} from "class-validator";
export class UserResponse {
    @IsNumber()
    id: number;
    @IsString()
    name: string;
    @IsString()
    email: string;
    @IsString()
    role: string;
}

arpitBhalla avatar Jul 04 '23 11:07 arpitBhalla

I have same problem with multiple body type, f.e. (it's only example for better understanding)

export class EmailUser {
	@IsNumber()
	public id: number;

	@IsEmail()
	public email: string;
}

export class PhoneUser {
	@IsNumber()
	public id: number;

	@IsPhoneNumber()
	public phoneNumber: number;
}

@JsonController()
export class UserController {

	@Post("/user")
	public addUser(
		@Req() req: Request,
		@Res() res: Response,
		@Body() body: EmailUser | PhoneUser
	): PhoneUser | EmailUser {
		if (body instanceof EmailUser) {
			//specific for user with email

			return body;
		}

		if (body instanceof PhoneUser) {
			//specific for user with phone number

			return body;
		}

		throw new Error('Unsupported type');
	}
}

Multiple types are necessary here and there is no possibility to change way how it works. For response schema I can easily use decorator @ResponseSchema more than one time and get multiple responses example as oneOf but i can't see any option for multiple body types.

Is it even possible?

klansser avatar Jan 09 '24 12:01 klansser