今天来聊下我在实际业务场景中抽出的一个node包--params-verifier,用于后端controller层的参数校验。
先来上个文档: www.npmjs.com/package/par…
Github repo: github.com/Yann-Wang/p…
接下来从四个方面来介绍下这个包:背景、使用、设计思路、完善方向。
背景
所负责的一个node项目,后端代码已达到7万行,业务已越来越复杂,与此同时,产生了一个现象:service层的业务逻辑中掺杂了很多参数校验的代码(由于历史原因,controller层没有做好充分的参数校验)。
这导致了下面的结果:
-
业务代码不能专注于业务逻辑
-
经常出现因为参数错误而导致的业务逻辑错误,并且不能直观定位
-
对于经常出现的动辄二三十个字段的表单提交接口,手写参数校验逻辑不仅麻烦而且写的不够严谨
这种情况困扰了我很久,于是,我开始寻找有没有合适的轮子帮我解决这个问题,然后发现了下面两个node包:
- validator : 这个包集成了很多常用的校验方法,但很多方法不一定会在参数校验场景中用得到,而且对于复合数据类型(Object)的内部字段校验也不支持,在写大表单的参数校验逻辑时,完全没有美感;
- node-validator : 这个包对 moment 有依赖,moment本身很重,导致这个包也会很重,而且它提供的使用方式我觉得看起来没有美感,尤其是针对Object中的字段的校验,这个在controller层的参数校验中很常用。
于是,我决定自己造个轮子,提供一个有预置校验器,并且可以自定义校验器的参数校验类。
使用
为了下面聊设计时不至于对这个包没有概念,我们先简单过下该包的使用姿势。
先丢一段校验object中字段的代码:
从使用者的角度看轮子的功能点
-
有一些确定的业务逻辑校验规则,可以通过指定规则名称来直接使用
-
支持自定义校验逻辑
-
支持字段非必填,可以同时支持表单字段校验(所有字段必填)和搜索条件字段校验(所有字段非必填)这两种业务场景。
设计思路
数据类型
首先,有个约定,只支持校验四种基础数据类型(string, number, boolean, date)和一种复合数据类型(object)。
说到这儿, 那顺便说下为啥只支持这四种基本数据类型呢,其实主要是从mysql中支持的数据类型方面来考虑的,mysql中支持的数据类型主要包括以下四种:
- 整数类型
- 浮点数类型, 定点数类型
- 日期和时间类型
- 字符串类型
1, 2 --> number, boolean
3 --> date
4 --> string
至于复合数据类型为什么只保留了object一种,是因为在koa中,对象类型最常用,而且参数一般是包裹在一个对象中传给后端的,而array不是太常用,所以暂不支持。
由此可见,params-verifier跟koa, mysql更配哦~~
UML类图
甩张UML类图,其实就是五种数据类型的子类对基类的继承。
参数在类方法中的流动顺序
主要包括两大块:
- 第一部分是校验参数校验方法的入参格式是否正确(checkOptionsParamsSupport);
- 第二部分是根据五步校验规则按顺序进行校验(startValidateProcedure);
每种数据类型只进行指定的部分校验步骤,如下:
校验顺序由上到下执行。
完善方向
-
增加更多的常用的业务校验逻辑,方便通过名称去配置校验规则
-
优化代码设计,打包方式,降低npm包的大小
-
支持前端引入
-
支持引入自定义的预置校验逻辑,并可以覆盖原有重名预置逻辑,方便通过指定预置逻辑名称来使用该逻辑进行校验
params-verifier特点
- 无依赖
- 体积小(核心代码,编译前600行, 编译后1000行)