gpt4 book ai didi

javascript - NestJS:如何在自定义验证器中同时访问 Body 和 Param?

转载 作者:行者123 更新时间:2023-12-01 15:27:09 24 4
gpt4 key购买 nike

我有一个场景,我需要参数和正文中的值来执行自定义验证。例如,我有一条路线 /:photoId/tag为照片添加标签。

但是,在向照片添加标签之前,它必须验证是否已经存在与照片同名的标签。

我的 Controller 中有以下路线:

@Post(':photoId/tag')
@UsePipes(new ValidationPipe())
async addTag(
@Param() params: AddTagParams,
@Body() addTagDto: AddTagDto
) {
// ...
}

由于 :photoId作为参数提供, tag在请求正文中提供,它们无法在自定义验证器中相互访问,我无法使用这两条信息对数据库进行检查:
export class IsPhotoTagExistValidator implements ValidatorConstraintInterface {

async validate(val: any, args: ValidationArguments) {
// supposed to check whether a tag of the same name already exists on photo
// val only has the value of photoId but not the name of the tag from AddTagDto in Body
}
}


export class AddTagParams{
@IsInt()
@Validate(IsPhotoTagExistValidator) // this doesn't work because IsPhotoTagExistValidator can't access tag in AddTagDto
photoId: number
}

export class AddTagDto{
@IsString()
tag: string
}

如上例所示, valIsPhotoTagExistValidator只是 photoId .但我需要 photoId在参数和 tag检查 Body 中的名称是否为特定 photoId已经有 tag .

我应该如何在自定义验证器函数中同时访问 Body 和 Param?如果没有,我应该如何解决这个问题?

最佳答案

到目前为止,我发现的唯一解决方案来自此评论 https://github.com/nestjs/nest/issues/528#issuecomment-497020970
context.interceptor.ts

import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common'
import { Observable } from 'rxjs'

/**
* Injects request data into the context, so that the ValidationPipe can use it.
*/
@Injectable()
export class ContextInterceptor implements NestInterceptor {
intercept(
context: ExecutionContext,
next: CallHandler
): Observable<any> {
const request = context.switchToHttp().getRequest();

request.body.context = {
params: request.params,
query: request.query,
user: request.user,
};

return next.handle()
}
}
main.ts
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalInterceptors(new ContextInterceptor());
// ...
}

如果您使用 {whitelist: true}ValidationPipe您需要允许的参数 context在您的 Dto 对象中。

这可以通过扩展这样的 Dto 来完成:
context-aware.dto.ts
import { Allow } from 'class-validator';

export class ContextAwareDto {
@Allow()
context?: {
params: any,
query: any,
user: any,
}
}

在此之后,您将能够通过 validationArguments.object.context 在自定义验证器中验证正文时访问请求数据

您可以在验证参数或查询时轻松调整上述内容以访问上下文,尽管我发现仅在正文验证期间拥有此内容就足够了。

关于javascript - NestJS:如何在自定义验证器中同时访问 Body 和 Param?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55481224/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com