在 NestJS 和 GraphQL 中使用 class-validator 支持对可选参数的验证?
Give support for validation on optional parameter using class-validator in NestJS and GraphQL?
我有这个 input
用于更新块。我希望用户可以更新名称或内容或两者。
现在的问题是,如果我只传递名称 GrapQL 会抛出一个错误,例如 Variable \"$updateBlockInput\" got invalid value { name: \"Updated again\" }; Field content of required type String! was not provided.
和 vice varsa.
我做错了什么?
更新-block.input.ts
import { InputType, Field } from '@nestjs/graphql';
import { IsOptional, IsNotEmpty } from 'class-validator';
@InputType()
export class UpdateBlockInput {
@IsOptional()
@IsNotEmpty()
@Field()
name?: string;
@IsOptional()
@IsNotEmpty()
@Field()
content?: string;
}
block.resolver.ts
...
@Mutation(returns => BlockType)
updateBlock(
@Args('id') id: string,
@Args('updateBlockInput') updateBlockInput: UpdateBlockInput,
) {
return this.blockService.update(id, updateBlockInput);
}
...
变异
mutation(
$id: String!
$updateBlockInput: UpdateBlockInput!
) {
updateBlock(
id: $id
updateBlockInput: $updateBlockInput
) {
name
content
}
}
变量
{
"id": "087e7c12-b48f-4ac4-ae76-1b9a96bbcbdc",
"updateBlockInput": {
"name": "Updated again"
}
}
如果它们是可选的,那么您需要避免使用 IsNotEmpty
并用 IsString
替换,表示如果存在该值,则它必须仅为字符串类型。
如果您想接受其中任何一个,但在未发送时失败,您需要编写自己的自定义验证器,因为开箱即用不支持这种情况。
一个例子:
import {ValidatorConstraint, ValidatorConstraintInterface} from 'class-validator';
@ValidatorConstraint({async: false})
export class IsInPast implements ValidatorConstraintInterface {
public validate(value: unknown): boolean {
if (typeof value !== 'string' && typeof value !== 'number') {
return false;
}
const now = new Date();
now.setHours(23);
now.setMinutes(59);
now.setSeconds(59);
now.setMilliseconds(999);
return `${value}`.match(/^\d+$/) !== null && `${value}` <= `${now.getTime()}`;
}
public defaultMessage(): string {
return 'Should be in past';
}
}
以及稍后在代码中的某处:
@Validate(IsInPast)
public dateField: string;
我有这个 input
用于更新块。我希望用户可以更新名称或内容或两者。
现在的问题是,如果我只传递名称 GrapQL 会抛出一个错误,例如 Variable \"$updateBlockInput\" got invalid value { name: \"Updated again\" }; Field content of required type String! was not provided.
和 vice varsa.
我做错了什么?
更新-block.input.ts
import { InputType, Field } from '@nestjs/graphql';
import { IsOptional, IsNotEmpty } from 'class-validator';
@InputType()
export class UpdateBlockInput {
@IsOptional()
@IsNotEmpty()
@Field()
name?: string;
@IsOptional()
@IsNotEmpty()
@Field()
content?: string;
}
block.resolver.ts
...
@Mutation(returns => BlockType)
updateBlock(
@Args('id') id: string,
@Args('updateBlockInput') updateBlockInput: UpdateBlockInput,
) {
return this.blockService.update(id, updateBlockInput);
}
...
变异
mutation(
$id: String!
$updateBlockInput: UpdateBlockInput!
) {
updateBlock(
id: $id
updateBlockInput: $updateBlockInput
) {
name
content
}
}
变量
{
"id": "087e7c12-b48f-4ac4-ae76-1b9a96bbcbdc",
"updateBlockInput": {
"name": "Updated again"
}
}
如果它们是可选的,那么您需要避免使用 IsNotEmpty
并用 IsString
替换,表示如果存在该值,则它必须仅为字符串类型。
如果您想接受其中任何一个,但在未发送时失败,您需要编写自己的自定义验证器,因为开箱即用不支持这种情况。
一个例子:
import {ValidatorConstraint, ValidatorConstraintInterface} from 'class-validator';
@ValidatorConstraint({async: false})
export class IsInPast implements ValidatorConstraintInterface {
public validate(value: unknown): boolean {
if (typeof value !== 'string' && typeof value !== 'number') {
return false;
}
const now = new Date();
now.setHours(23);
now.setMinutes(59);
now.setSeconds(59);
now.setMilliseconds(999);
return `${value}`.match(/^\d+$/) !== null && `${value}` <= `${now.getTime()}`;
}
public defaultMessage(): string {
return 'Should be in past';
}
}
以及稍后在代码中的某处:
@Validate(IsInPast)
public dateField: string;