san-validation
san-validation
提供了一系列简单的函数,基于jsen实现对象的验证,验证使用JSON Schema作为对象描述,返回错误信息与jsen一致。
本类库的validation
模块(也即主模块)为一个函数,称之为validation
函数,其签名如下:
{Function} validation({Object} schema, {Object | null} messages, {Object} [options])
该函数返回一个函数,用于对输入进行校验,校验返回一个对象,结构如下:
{
{boolean} isValid,
[Object[]] errors
}
其中errors
对象为jsen返回的结果,具体请查看jsen的相关API。
普通的使用方法:
; let validate = ; let isValid errors = ;if !isValid ;
消息分离
在一些业务中,同样的JSON Schema会用于不同的视图界面,在不同的界面则要应用不同的错误信息。本类库支持将JSON Schema中的结构描述与错误信息进行分离,这么做也可以让schema更纯粹地描述一个对象的结构,而与校验有关的信息则在实际进行校验时再提供。
使用validation
函数的第二个参数可以对原有的schema添加错误信息,假设我们的原schema如下:
let schema = type: 'object' description: 'product' properties: categoryId: type: 'number' description: 'category' tags: type: 'array' description: 'tags' minItems: 1 uniqueItems: true items: type: 'string' description: 'tag of product' maxLength: 30 sales: type: 'array' items: type: 'object' properties: year: type: 'number' description: 'sales year' minimum: 1900 month: type: 'number' description: 'sales month' minimum: 1 maximum: 12 quantity: type: 'number' description: 'sales quantity' minimum: 0 required: 'categoryId' 'sales'
对应的message
对象如下:
let message = type: 'Invalid ${description} type' categoryId: type: 'Invalid ${description} type' tags: minItems: 'There should be no less than ${minItems} ${description}' uniqueItems: 'Duplicate ${description}' items: type: '${description} should be ${type}s' maxLength: 'Each ${description} should have no more than ${maxLength} characters' sales: items: year: minimum: '${description} is too early' month: minimum: '${description} should fall within 1 - 12' maximum: '${description} should fall within 1 - 12' quantity: minimum: 'Need a positive ${description}'
在message
对象中,可以使用${xxx}
占位符输出,占位符可用的内容与这个字段的schema中的属性对应,但并不会向上或向下找父字段/子字段的相关属性。
validation
函数会将message
中的各个错误消息合并到schema中,大致的合并算法如下:
- 找到
invalidMessage
和requiredMessage
直接与原schema合并,从message
中移除这2个属性 message
的每个属性,如果值为字符串则是一个错误消息模板,如果是对象则为更进一步的属性-错误信息配置。- 将同级别的
message
中错误信息提取出来,作为messages
属性与原schema合并 - 将其它属性提取出来,如果原schema的
type
为object
,则作为properties
与原schema合并 - 如果原schema的
type
为array
,则提取items
属性与原schema合并
因此基于上面的结构,我们可以进行校验:
let product = categoryId: 'invalid' tags: 'x' 'x' 123 sales: year: 1800 month: 14 quantity: -23 ; let isValid errors = product;
这样我们可以得到以下的错误errors
对象:
path: 'categoryId' keyword: 'type' message: 'Invalid category type' path: 'tags' keyword: 'uniqueItems' message: 'Duplicate tags' path: 'tags.0' keyword: 'maxLength' message: 'Each tag of product should have no more than 30 characters' path: 'tags.1' keyword: 'maxLength' message: 'Each tag of product should have no more than 30 characters' path: 'tags.2' keyword: 'type' message: 'tag of product should be strings' path: 'sales.0.year' keyword: 'minimum' message: 'sales year is too early' path: 'sales.0.month' keyword: 'maximum' message: 'sales month should fall within 1 - 12' path: 'sales.0.quantity' keyword: 'minimum' message: 'Need a positive sales quantity'
可以看到每一个错误对象都使用了message
配置中对应的消息,对于数组则使用的items
中配置的消息。
默认错误信息
大部分业务项目有一套默认的错误信息规则,如所有“必填”字段的提示均为“XXX字段为必填项”,我们不希望每次编写schema时都对这些字段一一指明错误信息,因此san-validation
提供了支持默认错误信息的功能。
validation
模块的withDefaultMessages
函数接收一个默认消息配置对象,返回一个新的validation
函数。
默认消息配置对象的每个键对应一个错误类型(如type
、minLength
、maximum
等),值为一个函数,该函数接收当前字段的schema,需要返回错误信息字符串。
我们通常推荐一个项目独立一个模块提供自己的validation
函数,可在这个模块内配置默认错误信息,如编写一个common/validation.js
文件,可以使用以下代码提供默认的错误信息:
/** * @file common.validation.js */ ; let messages = `的类型不符` { if minLength === 1 return `必须输入`; return `不得小于个字符`; } ...; messages;
其它模块则直接使用项目中的validation
模块:
;; // 额外的错误信息let errorMessages = roles: items: oneOf: '用户角色必须为“正常用户”、“VIP”、“管理员”之一' ;let validateUser = ; { return ; }
基于源码构建
除了包目录下的validation.js
和validation.min.js
外,可以直接基于src
目录下的源码进行构建,需要使用babel及es2015
预设集。