实现nest的自定义注解

简介: 实现nest的自定义注解

前言

             

Nest 与 class-validator[1] 配合得很好,它允许我们使用基于装饰器的验证,在dto层中我们可以通过它的一些内置注解完成对参数的一些常用校验。    

但是,当我们在写业务代码时,内置注解往往不能满足我们,此时我们为了代码的一致性,就需要根据需求自定义一个注解出来,本文将带着大家一起实现一个注解,欢迎各位感兴趣的开发者阅读本文。


场景概述


客户端传入一个不符合规范的json字符串,我们需要对其进行截取后,再转成json对象进行下一步的校验,客户端传入的字符串如下所示:


var config = '{"name":"aa","age":"21","title":"标题测试"}'


在处理的时候,需要把var config =截取掉,只保留json字符串,然后转成json对象,要求属性总数必须大于2,我们很容易就能写出代码来,如下所示:


// 验证配置字符串是否符合规范
export function verifyConfig(
  draftConfig?: string
): boolean | Record<string, any> {
  // 去除多余字符
  if (draftConfig && draftConfig.length >= 12) {
    draftConfig = draftConfig.substring(12, draftConfig.length);
  }
  let draftData = {};
  try {
    if (typeof draftConfig === "string") {
      draftData = JSON.parse(draftConfig);
    }
    // 草稿json字段不足
    if (Object.keys(draftData).length < 2) {
      return false;
    }
  } catch (e) {
    // 草稿配置数据格式错误
    return false;
  }
  return draftData;
}


实现思路


本文继续沿用文章“使用NestJS搭建服务端应用[2]”所创建的项目,以此为基础进行扩展。


我们在阅读class-validator仓库文档的custom-validation-decorators[3]章节后,大概了解了它的流程,接下来我们来实践它。


注册装饰器


首先,我们在项目根录下创建decorators文件夹,所有注解的实现文件都会放在此目录下。随后我们在其目录下创建ConfigDecor.ts文件。


我们通过registerDecorator方法来注册一个装饰器,代码如下所示:


  • IsConfig 为注解的名称,它是函数类型,接受一个ValidationOptions类型的可选参数
  • 装饰器注册函数中有一个validator属性,用于校验数据,将在下个章节进行详细讲解


// 配置验证注解
export function IsConfig(validationOptions?: ValidationOptions) {
  return function (object: Record<string, any>, propertyName: string): void {
    // 注册一个装饰器
    registerDecorator({
      name: "IsConfig",
      target: object.constructor,
      options: validationOptions,
      propertyName: propertyName,
      validator: IsConfigConstraint
    });
  };
}


数据校验类


装饰器的validator属性值是一个用@ValidatorConstraint装饰的一个类,这个类必须实现ValidatorConstraintInterface接口。其代码如下所示:


  • validate 接受的参数就是dto中使用注解的字段所对应的值,我们需要的就是对它进行校验,校验函数就是用我们在文章开头写好的verifyConfig方法。
  • defaultMessage 就是验证不通过时,默认返回给客户端的报错信息


// 配置验证程序
@ValidatorConstraint({ async: true })
export class IsConfigConstraint implements ValidatorConstraintInterface {
  validate(value: string): Promise<boolean> | boolean {
    // 对草稿配置进行校验
    // 校验程序返回值为boolean类型则代数据格式错误
    return typeof verifyConfig(value) !== "boolean";
  }
  // 验证失败时的默认错误信息
  defaultMessage(args: ValidationArguments): string {
    return `property ${args.property} data format error`;
  }
}


使用装饰器


最后,我们只需要像使用内置装饰器一样使用它就可以了,代码如下所示:


export class AppDto {
  @MinLength(5)
  @IsString()
  public id!: string;
  @IsString()
  public title!: string;
  @IsString()
  public name!: string;
  @IsConfig()
  public config!: string;
}


最后,我们启动项目,使用postman对其进行测试,如下图所示:


  • 我们传了一个不符合规范的字符串,装饰器校验不通过,返回了我们定义好的默认校验信息。


640.png

                           image-20220217012646287


我们在来测试下正确数据的情况,如下图所示,成功调用:


640.png

                                 image-20220217012920927


小tip: 我们在注册装饰器时,提供了一个可选参数,它的作用就是为了其能像内置注解一样,修改其公开属性,例如message,我们可以对验证失败时的错误信息进行自定义。

640.png

                               image-20220217013237077


示例代码


本文中所列举的完整代码请移步:


  • JsonDataVerifyUtilas.ts[4]
  • ConfigDecor.ts[5]
  • AppDto[6]


写在最后


至此,文章就分享完毕了。


我是神奇的程序员,一位前端开发工程师。


如果你对我感兴趣,请移步我的个人网站[7],进一步了解。


  • 公众号无法外链,如果文中有链接,可点击下方阅读原文查看😊
相关文章
|
编解码 人工智能
全球二氧化碳排放数据1deg产品(ODIAC)数据
全球二氧化碳排放数据1deg产品(ODIAC)数据
459 0
|
存储 消息中间件 架构师
如何估算集群所需的存储、计算资源?
如何估算集群所需的存储、计算资源?
|
关系型数据库 MySQL Linux
【Linux环境】centos安装mysql5.7.26报 ./mysqld: error while loading shared libraries: libaio.so.1: cannot op
【Linux环境】centos安装mysql5.7.26报 ./mysqld: error while loading shared libraries: libaio.so.1: cannot op
1294 0
|
机器学习/深度学习 算法 Python
深度解析机器学习中过拟合与欠拟合现象:理解模型偏差背后的原因及其解决方案,附带Python示例代码助你轻松掌握平衡技巧
【10月更文挑战第10天】机器学习模型旨在从数据中学习规律并预测新数据。训练过程中常遇过拟合和欠拟合问题。过拟合指模型在训练集上表现优异但泛化能力差,欠拟合则指模型未能充分学习数据规律,两者均影响模型效果。解决方法包括正则化、增加训练数据和特征选择等。示例代码展示了如何使用Python和Scikit-learn进行线性回归建模,并观察不同情况下的表现。
1629 3
|
7月前
|
存储 虚拟化 数据中心
VMware ESXi 8.0U3e macOS Unlocker & OEM BIOS Lenovo (联想) 定制版
VMware ESXi 8.0U3e macOS Unlocker & OEM BIOS Lenovo (联想) 定制版
170 2
|
机器学习/深度学习 API 网络架构
"解锁机器学习超级能力!Databricks携手Mlflow,让模型训练与部署上演智能风暴,一触即发,点燃你的数据科学梦想!"
【8月更文挑战第9天】机器学习模型的训练与部署流程复杂,涵盖数据准备、模型训练、性能评估及部署等步骤。本文详述如何借助Databricks与Mlflow的强大组合来管理这一流程。首先需在Databricks环境内安装Mlflow库。接着,利用Mlflow跟踪功能记录训练过程中的参数与性能指标。最后,通过Mlflow提供的模型服务功能,采用REST API或Docker容器等方式部署模型。这一流程充分利用了Databricks的数据处理能力和Mlflow的生命周期管理优势。
580 7
|
数据可视化 Apache 索引
Vue3使用echarts仪表盘(gauge)
Apache ECharts 是一款强大的数据可视化库,其仪表盘图表(`gauge`)可用于展示度量数据。主要属性包括仪表盘数据源 `gaugeData`(必填)、容器宽度 `width`(默认 100%)及高度 `height`(默认 100%)。数据项需指定名称 `name` 和值 `value`,并支持额外属性。
1820 2
Vue3使用echarts仪表盘(gauge)
|
机器学习/深度学习 算法 数据挖掘
8个常见的机器学习算法的计算复杂度总结
8个常见的机器学习算法的计算复杂度总结
324 4
8个常见的机器学习算法的计算复杂度总结
|
消息中间件 负载均衡 监控
Kafka消费者:监听模式VS主动拉取,哪种更适合你?
Kafka消费者:监听模式VS主动拉取,哪种更适合你?
463 1
|
移动开发 前端开发 JavaScript
快速上手web前端开发(超详细教程)
快速上手web前端开发(超详细教程)

热门文章

最新文章