文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

实现 Nest 的自定义注解,你会了吗?

2024-12-02 07:16

关注

前言

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方法来注册一个装饰器,代码如下所示:

// 配置验证注解
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接口。其代码如下所示:

// 配置验证程序
@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对其进行测试,如下图所示:

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

image-20220217012646287

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

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

示例代码

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

写在最后至此,文章就分享完毕了。

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

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

公众号无法外链,如果文中有链接,可点击下方阅读原文查看😊

参考资料

[1]class-validator: https://github.com/pleerock/class-validator

[2]使用NestJS搭建服务端应用: https://juejin.cn/post/7053840108331466783

[3]custom-validation-decorators: https://github.com/typestack/class-validator#custom-validation-decorators

[4]JsonDataVerifyUtilas.ts: https://github.com/likaia/nest-project/blob/9c25cc367c83e28331cdd52a2bf3ce538f35400c/src/utils/JsonDataVerifyUtilas.ts#L2

[5]ConfigDecor.ts: https://github.com/likaia/nest-project/blob/9c25cc367c83e28331cdd52a2bf3ce538f35400c/src/decorators/ConfigDecor.ts#L11[

6]AppDto: https://github.com/likaia/nest-project/blob/9c25cc367c83e28331cdd52a2bf3ce538f35400c/src/dto/AppDto.ts#L4

[7]个人网站: https://www.kaisir.cn/


来源:神奇的程序员内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯