不想再做唯一值判断? 来看看dto的自定义校验规则

前言

在我们的开发中经常需要验证字段唯一性,比如当我们注册账号的时候,经常要判断用户有没有注册过,对于字段较少的还好,如果有很多字段都需要判断,那我们就需要查很多字段,在代码中写一堆这个东西,看着挺不舒服的,就比如下面这样

我们对于这四个唯一字段每次创建前都需要判断,而且其他服务创建前都有某个或某些字段需要判断唯一性,那么我们能不能封装一个方法,来简化这种操作呢。当然有,下面进入我们的正题。

本章所需知识

  • nestjs
  • prisma
  • mysql
  • class-validator

封装方法

我们在做dto 验证的时候大概都用过class-validator这个包,我这里就不介绍了,一个验证规则包,本文主要就是讲它的自定义校验规则。

github上找到这个,然后看他下面的文档

找到这俩,一个是自定义验证类,一个是自定义装饰器,他们都可以,本文都会介绍到。根据文档指引,我们先把模板搭建好。

自定义验证类

现在就在dto里面写自定义验证类

resgister.dto.ts 复制代码
import { IsNotEmpty, Validate } from 'class-validator'
import { IsExistRule } from './custom/is_exist'

export class registerDto {
  
  @Validate(IsExistRule, {
    message: '用户名已存在'
  })
  @IsNotEmpty({message: '用户名不能为空'})  
  username: string

  @IsNotEmpty({message: '密码不能为空'})  
  password: string
}

我们可以看到text 字段以及agrs 代表什么,如果只是这样,那我们每次在内部进行唯一性判断的时候,表名就定死了,有没有什么办法呢,当然有,我们可以看到args里面的constraints为undefined,这个关联值,我们可以设置为表名

那么我们可以每次都拿这个关联值就可以动态表名了,但这里我们就可以开始了。

这里的逻辑就写完了,测试就不给大家展示了,感兴趣的可以自己用测试工具测一下,另外dto的验证错误捕获,对于不是很复杂的项目,大可用系统内置的validatePipe来捕获

自定义验证装饰器

其实也就是写法不一样,看到这些属性名就很熟悉,和刚刚的差不多

is_not_exist.ts 复制代码
import { PrismaClient } from '@prisma/client';
import { registerDecorator, ValidationOptions, ValidationArguments } from 'class-validator';

export function IsNotExist(property: string, validationOptions?: ValidationOptions) {
  return function (object: Object, propertyName: string) {
    registerDecorator({
      name: 'IsNotExist',
      target: object.constructor,
      propertyName: propertyName,
      constraints: [property],
      options: validationOptions,
      validator: {
        async validate(value: any, args: ValidationArguments) {
            
          const prisma = new PrismaClient

          const tableName = args.constraints[0]
          const property = args.property
            
          const res = await prisma[tableName].findUnique({
            where: {
              [property]: value
            }
          })
         return res
        },
      },
    });
  };
}
login.dto.ts 复制代码
import { IsNotEmpty, Validate } from 'class-validator'
import { IsNotExist } from './custom/is_not_exist'

export class LoginDto {
  
  @IsNotExist('user', {
    message: '用户不存在'
  })
  @IsNotEmpty({message: '用户名不能为空'})  
  username: string

  @IsNotEmpty({message: '密码不能为空'})  
  password: string
}

当我们登陆的时候往往需要判断是否有这个值,可以这样来判断,但是不建议哈,因为本身字段就少,我们写这么多代码得不偿失,但是上面那个就可以,应用场景我们也能用的到。

结语

通过本章你可以学习到自定义验证的用法,可以对你的代码结构进行简化,也可以满足你的验证需求,希望大家能够有所收获!😘

相关推荐
counterxing2 小时前
我整理了一个免费开发资源目录,还做成了 CLI 和 MCP
前端·agent·ai编程
子兮曰9 小时前
Bun v1.3.14 深度解析:Image API、HTTP/3、全局虚拟存储与五十项变革
前端·后端·bun
kyriewen10 小时前
今天,百年巨头一次砍了9200人,而一个离职科学家的实话让全网睡不着觉
前端·openai·ai编程
问心无愧051310 小时前
ctf show web 入门42
android·前端·android studio
kyriewen11 小时前
老板逼我上AI,我偷偷在浏览器里跑LLaMA,省下20万API费
前端·react.js·llm
Beginner x_u11 小时前
前端八股整理(手写 02)|数组转树、数组扁平化、随机打乱一个数组
前端·数组·数组转树·数组扁平化
KaMeidebaby11 小时前
卡梅德生物技术快报|禽类成纤维细胞 FISH 实验:鸟类性别染色体基因定位技术实现与数据验证
前端·数据库·其他·百度·新浪微博
天若有情67311 小时前
前端高阶性能优化:跳出传统懒加载与预加载,基于用户行为做轻量预判加载
前端·性能优化
小小小小宇11 小时前
前端转后端:SQL 是什么
前端
张元清12 小时前
React Observer Hooks:7 种监听 DOM 而不写样板代码的方式
前端·javascript·面试