如何在 nest.js 中创建装饰器?
How to create decorator in nest.js?
我为此烦恼了好一阵子。我的装饰器应该提供用于检查字段的唯一值的信息。看起来是这样的:
export const IsUnique = (
metadata: {
entity: any,
field: string,
},
): PropertyDecorator => {
return createPropertyDecorator(constants.custom_decorators.is_unique, metadata);
};
我的验证是这样的:
import { HttpException } from '@nestjs/common';
import { PipeTransform, Pipe, ArgumentMetadata, HttpStatus } from '@nestjs/common';
import {validate, ValidationError} from 'class-validator';
import { plainToClass } from 'class-transformer';
import constants from '../../../constants';
@Pipe()
export class ValidationPipe implements PipeTransform<any> {
async transform(value, metadata: ArgumentMetadata) {
console.log(arguments);
const { metatype } = metadata;
if (!metatype || !this.toValidate(metatype)) {
return value;
}
const object = plainToClass(metatype, value);
const errors = await validate(object);
const myErrors = await this.uniqueValidation(object);
if (errors.length > 0) {
throw new HttpException(errors, HttpStatus.BAD_REQUEST);
}
return value;
}
private toValidate(metatype): boolean {
const types = [String, Boolean, Number, Array, Object];
return !types.find((type) => metatype === type);
}
private async uniqueValidation(object): Promise<ValidationError[]|null>{
const md = Reflect.getMetadata('swagger/apiModelPropertiesArray', object);
console.log(md);
return null;
}
}
执行代码后,看起来像 md=undefined。那么我如何检索我的元数据呢?也许,我以错误的方式使用了 createPropertyDecorator?
编辑:
几个小时后,我意识到 nestjs 没有 "createPropertyDecorator",我从 swagger 模块导入它(大错误)。所以我需要创建自己的函数。现在我是这样做的:
export const IsUnique = (
metadata: {
entity: any,
field: string,
},
): PropertyDecorator => {
return (target: object, propertyKey: string) => {
const args = Reflect.getMetadata(constants.custom_decorators.is_unique, target, propertyKey) || {};
const modifiedArgs = Object.assign(args, { IsUnique: metadata.field });
Reflect.defineMetadata(constants.custom_decorators.is_unique, modifiedArgs, target);
};
};
所以,我的问题是一样的 - 如何正确定义元数据,使其永远不会干扰其他人?
我为此使用不同的方法我使用 class 验证器
export class SignInUser {
@IsEmail()
email: string;
@Length(6, 50)
password: string;
}
并在控制器中
signIn(@Body(new ValidationPipe()) signIn: SignInUser) {}
它就像一个魅力
NOTE: I use ValidationPipe from @nestjs/common
并且您可以为 class 验证器
创建自己的装饰器
https://github.com/typestack/class-validator#custom-validation-decorators
我为此烦恼了好一阵子。我的装饰器应该提供用于检查字段的唯一值的信息。看起来是这样的:
export const IsUnique = (
metadata: {
entity: any,
field: string,
},
): PropertyDecorator => {
return createPropertyDecorator(constants.custom_decorators.is_unique, metadata);
};
我的验证是这样的:
import { HttpException } from '@nestjs/common';
import { PipeTransform, Pipe, ArgumentMetadata, HttpStatus } from '@nestjs/common';
import {validate, ValidationError} from 'class-validator';
import { plainToClass } from 'class-transformer';
import constants from '../../../constants';
@Pipe()
export class ValidationPipe implements PipeTransform<any> {
async transform(value, metadata: ArgumentMetadata) {
console.log(arguments);
const { metatype } = metadata;
if (!metatype || !this.toValidate(metatype)) {
return value;
}
const object = plainToClass(metatype, value);
const errors = await validate(object);
const myErrors = await this.uniqueValidation(object);
if (errors.length > 0) {
throw new HttpException(errors, HttpStatus.BAD_REQUEST);
}
return value;
}
private toValidate(metatype): boolean {
const types = [String, Boolean, Number, Array, Object];
return !types.find((type) => metatype === type);
}
private async uniqueValidation(object): Promise<ValidationError[]|null>{
const md = Reflect.getMetadata('swagger/apiModelPropertiesArray', object);
console.log(md);
return null;
}
}
执行代码后,看起来像 md=undefined。那么我如何检索我的元数据呢?也许,我以错误的方式使用了 createPropertyDecorator?
编辑: 几个小时后,我意识到 nestjs 没有 "createPropertyDecorator",我从 swagger 模块导入它(大错误)。所以我需要创建自己的函数。现在我是这样做的:
export const IsUnique = (
metadata: {
entity: any,
field: string,
},
): PropertyDecorator => {
return (target: object, propertyKey: string) => {
const args = Reflect.getMetadata(constants.custom_decorators.is_unique, target, propertyKey) || {};
const modifiedArgs = Object.assign(args, { IsUnique: metadata.field });
Reflect.defineMetadata(constants.custom_decorators.is_unique, modifiedArgs, target);
};
};
所以,我的问题是一样的 - 如何正确定义元数据,使其永远不会干扰其他人?
我为此使用不同的方法我使用 class 验证器
export class SignInUser {
@IsEmail()
email: string;
@Length(6, 50)
password: string;
}
并在控制器中
signIn(@Body(new ValidationPipe()) signIn: SignInUser) {}
它就像一个魅力
NOTE: I use ValidationPipe from @nestjs/common
并且您可以为 class 验证器
创建自己的装饰器https://github.com/typestack/class-validator#custom-validation-decorators