如何解决使用@ApiParam的嵌套路由,如何在nestjs中使用自定义验证器?
我正在寻找有关Nest中的自定义验证器和自定义装饰器的帮助。
第一种情况:可以解决
带有类验证器注释的DTO:
import { IsNotEmpty,IsString } from 'class-validator';
import { IsOwnerExisting } from '../decorators/is-owner-existing.decorator';
export class CreatePollDto {
@IsNotEmpty()
@IsString()
@IsOwnerExisting() // custom decorator,calling custom validator,using a service to check in db
ownerEmail: string;
@IsNotEmpty()
@IsString()
@NotContains(' ',{ message: 'Slug should NOT contain any whitespace.' })
slug: string;
}
我在控制器中使用它:
@Controller()
@ApiTags('/polls')
export class PollsController {
constructor(private readonly pollsService: PollsService) {}
@Post()
public async create(@Body() createPollDto: CreatePollDto): Promise<Poll> {
return await this.pollsService.create(createPollDto);
}
}
当调用此端点时,dto正在由类验证器进行验证,并且我的自定义验证器可以工作。如果该电子邮件不适合数据库中的任何用户,则会显示默认消息。 这就是我的理解。
第二种情况:如何使其工作?
现在,我想使用ApiParam在嵌套路由中执行类似的操作。我想用自定义验证器检查参数是否匹配数据库中的某些对象。
在这种情况下,我无法在dto中使用装饰器,因为dto无法处理“子弹”属性,它是ManyToOne,而该属性在另一侧。
// ENTITIES
export class Choice {
@ManyToOne((type) => Poll)
poll: Poll;
}
export class Poll {
@Column({ unique: true })
slug: string;
@OneToMany((type) => Choice,(choice) => choice.poll,{ cascade: true,eager: true })
@JoinColumn()
choices?: Choice[];
}
// DTOs
export class CreateChoiceDto {
@IsNotEmpty()
@IsString()
label: string;
@IsOptional()
@IsString()
imageUrl?: string;
}
export class CreatePollDto {
@IsNotEmpty()
@IsString()
@NotContains(' ',{ message: 'Slug should NOT contain any whitespace.' })
slug: string;
@IsOptional()
@IsArray()
@ValidateNested({ each: true })
@Type(() => CreateChoiceDto)
choices: CreateChoiceDto[] = [];
}
那我应该在哪里进行验证?
我想直接在控制器中使用一些装饰器。我不知道这可能不是个好地方。我也可以在服务中做到这一点。
@Controller()
@ApiTags('/polls/{slug}/choices')
export class ChoicesController {
constructor(private readonly choicesService: ChoicesService) {}
@Post()
@ApiParam({ name: 'slug',type: String })
async create(@Param('slug') slug: string,@Body() createChoiceDto: CreateChoiceDto): Promise<Choice> {
return await this.choicesService.create(slug,createChoiceDto);
}
}
在我的第一种情况下,我想在控制器的create方法中使用以下代码。
@ValidatorConstraint({ async: true })
export class IsSlugMatchingAnyExistingPollConstraint implements ValidatorConstraintInterface {
constructor(@Inject(forwardRef(() => PollsService)) private readonly pollsService: PollsService) {}
public async validate(slug: string,args: ValidationArguments): Promise<boolean> {
return (await this.pollsService.findBySlug(slug)) ? true : false;
}
public defaultMessage(args: ValidationArguments): string {
return `No poll exists with this slug : $value. Use an existing slug,or register one.`;
}
}
你知道我想做什么吗?可行吗?有什么好的方法?
非常感谢!
解决方法
如果您需要使用自定义规则来验证段,则可以选择以下两种方式之一
-
创建一个不使用class-validator的自定义管道,并直接在其中进行验证。
-
使用
@Param() { slug }: CreatePollDto
。假设所有内容都将通过URL参数发送。您总是可以将DTO简化为
export class SlugDto {
@IsNotEmpty()
@IsString()
@NotContains(' ',{ message: 'Slug should NOT contain any whitespace.' })
slug: string;
}
然后使用@Param() { slug }: SlugDto
,现在Nest将通过ValidationPipe
为您进行验证。
如果它不能与您一起使用,请尝试使用
getConnection().createQueryBuilder().select().from().where()
我在自定义装饰器中使用了它,使它成为isUnique,并且效果很好,但可注入服务却无法实现。
public async validate(slug: string,args: ValidationArguments): Promise<boolean> { return (await getConnection().createQueryBuilder().select(PollsEntityAlias).from(PollsEntity).where('PollsEntity.slug =:slug',{slug}))) ? true : false; }
太贪心了!非常感谢,它正在工作。
我已经尝试过类似的方法,但是找不到好的方法。
解构的{ slug }: SlugDto
,非常棘手和聪明!我已经尝试过slug : SlugDto
,但无法正常工作,就像«..hmmm ...如何做到那样……»
还有其他事情:在控制器方法中,我正在使用(如文档中所述)@Param('slug')
,但是使用slugDto时,它不起作用。相反,它必须只是@Param()
。
最后,我的方法:
@Post()
@ApiParam({ name: 'slug',type: String })
public async create(@Param() { slug }: SlugDto,@Body() createChoiceDto: CreateChoiceDto): Promise<Choice> {
return await this.choicesService.create(slug,createChoiceDto);
}
还有dto:
export class SlugDto {
@IsNotEmpty()
@IsString()
@NotContains(' ',{ message: 'Slug should NOT contain any whitespace.' })
@IsSlugMatchingAnyExistingPoll()
slug: string;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。