Abdulla Qurbonov
Abdulla Qurbonov

Reputation: 21

How to make one of two fields required in Nestjs DTO with its proper API documentation?

For example:

{
  phone: string 
  email: string
  ....
  ....
  otherFields
  ....
  ....
}

Either phone or email should be required in request body. I found solution only for validation, here is:

export class MyDto {
   @IsString()
   @ValidateIf((obj, value) => !obj.email || value)
   phone: string;

   @IsString()
   @ValidateIf((obj, value) => !obj.phone || value)
   phone: string;

   ..... other fields .....
  }

However, how to apply swagger documentation for this? There are oneOf and anyOf in OAS3 docs. Here is suitable solution in terms of swagger: link

How is it possible to implement both validation and swagger docs at the same time?

Upvotes: 2

Views: 7728

Answers (1)

GFoniX
GFoniX

Reputation: 334

The only alternative that I see for your problem is this.

export class EmailDto {
  @ApiProperty()
  @IsString()
  email: string;
}

export class PhoneDto {
  @ApiProperty()
  @IsString()
  phone: string;
}

export class CreateCatDto {
  @ApiProperty({
    oneOf: [
      {
        type: 'object',
        required: ['phoneNumber'],
        properties: {
          phoneNumber: { type: 'string' },
        },
      },
      {
        type: 'object',
        required: ['email'],
        properties: { email: { type: 'string' } },
      },
    ],
  })
  @ValidateNested()
  @Type((type) => (type.object.phoneOrEmail.email ? EmailDto : PhoneDto))
  phoneOrEmail: PhoneDto | EmailDto;
}

Here you have the documentation for anyOf in NestJs I didn't use getSchemaPath because my schema wasn't initialised by Swagger so I create manually my schema in @ApiProperty

And for the class-validator I ask to validate the DTO for the right Type with @ValidateNested() and @Type().

The problem is. If they sent you both email and phoneNumber class-validator will only validate email because:

(type.object.phoneOrEmail.email ? EmailDto : PhoneDto)

If there is an email, it will validate the class EmailDto first. So you need to tell if there are Email and PhoneNumber you need to validate a DTO with both.

Go check on Google if there is an anyOf like for class-validaor

Upvotes: 3

Related Questions