日常作业中免不了频繁处理 GET/POST 的入参,你当然可以每个 action 中都重复地去做这些事情,

  • 从 query 或 body 取出入参,
  • 对可选的入参进行判空,
  • 处理入参的类型转换,
  • 对入参进行逻辑校验,数字是否超限,类型是否非法等...

但这些通用的逻辑可通过抽取到插件或服务中,避免代码冗余和重复劳动。

egg-validation

Egg.js 中可通过 egg-validation 插件来减少这部分的工作量。通过该插件,上面大部分工作可转成简单的配置。

安装插件

$ yarn add egg-validate

配置插件

启用:

config/plugin.ts

const plugin: EggPlugin = {
// ...
validate: {
enable: true,
package: 'egg-validate',
},
// ...
}; export default plugin;

配置插件:

config/config.default.ts

export default (appInfo: EggAppInfo) => {
const config = {} as PowerPartial<EggAppConfig>; // ...

config.validate = {

convert: true,

widelyUndefined:true

}; // ...

};

其配置项为 node-modules/parameter 的所有可用配置项,因为该插件其实就是后者的 Egg.js 封装。

  • convert 会对入参进行转换,建议开启。举个例子,使用表单中默认的 submit 类型按钮提交表单时,提交过来的往往是序列化后的字符串,那些期望是数字类型的字段就会始终验证不过。而开启此项后,会对入参按希望的类型进行转换。
  • widelyUndefined 开启后,会把空字符串,NaN,null 这些转成 undefined,将这些异常的数据进行了统一,方便后续处理。

使用

插件在 appcontext 上扩展了 validator 对象,通过调用 validator.validate(rules,data) 来进行验证。

比如接收一个名为 name 的字符串入参:

app/controller/home.ts

const errors = this.app.validator.validate({ name: 'string' }, this.request.body);
if (errors) {
this.ctx.body = errors;
}

验证规则

validate 第一个参数为规则,它是个对象。其每个字段对应同名的入参。字段的值可以是简单的字符串,指定字段的类型,也可以是对象,在这个对象里进行更加详细的规则指定。

const rules = {
param1: 'string', // 必填的字符串入参
param2: 'string?', // 可选的字符串入参
param3: {
type: 'int', // 整形入参
required: false, // 该入参可选
min: 0, // 该入参的最小值
max: 10, // 该入参的最大值
},
};

规则默认入参是必填的,对于可选的入参,可通过在类型后加问号,与 TypeScript 类似,也可以显式指定 required: false

预设可用的参数类型参见 parameter

针对参数的规则配置,根据参数的类型,有不同的配置顶,比如对于数字类型,可配置其最大最小值;对于枚举,可定义其候选值,一旦入参不在这些值之内,便验证不通过。每种类型可用的配置项参见 parameter

自定义验证规则

如果上面文档中预设的这些类型无法满足需求,可通过 validator.addRule(type,checker) 自定义规则来扩充。

其中 type 为新增规则的类型名, checker 为用来校验的正则或方法。如果是个方法,其入参为规则本身及需要校验的数据,文档里没有体现其入参,可参考源码

checker.call(self, rule, obj[key], obj);

比如增加一种类型为 jsonString 的验证规则,限定入参必需为合法的 JSON 数据。

app.ts

export default (app) => {
app.validator.addRule('jsonString', (_rule, value) => {
try {
JSON.parse(value);
} catch (err) {
return 'must be json string';
}
});
};

示例代码

一个可本地运行调试,配合了预设的验证规则及自定义的规则的示例,完整代码可在 GitHub 找到。

结论

写了过多的重复的代码后,比如这种入参的校验,就应该想想如何优雅地来处理这些重复的工作,无论是自己造轮子,还是找轮子。入参的校验如此之常见,进而,甚至可以去追求一套前后台通用的校验逻辑,将浏览器端的 JavaScript 与 Node.js 的逻辑进行统一。

相关资源

Egg.js 中入参的校验的更多相关文章

  1. 在egg.js中使用mongodb

    1.egg.js官网只推荐了mysqle,要用mongodb得另找资料.通过查找,大家都在用Mongoose连接,于是乎学习. 网站链接:https://www.npmjs.com/package/e ...

  2. Egg.js中使用sequelize事务

    对数据库的操作很多时候需要同时进行几个操作,比如需要同时改动几张表的数据,或者对同一张表中不同行(row)或列(column)做不同操作,比较典型的例子就是用户转账问题(A账户向B账号汇钱): 1 从 ...

  3. SpringBoot2 参数管理实践,入参出参与校验

    一.参数管理 在编程系统中,为了能写出良好的代码,会根据是各种设计模式.原则.约束等去规范代码,从而提高代码的可读性.复用性.可修改,实际上个人觉得,如果写出的代码很好,即别人修改也无法破坏原作者的思 ...

  4. egg.js路由的优雅改造

    引言 在使用express,koa, 或者是egg.js进行node server开发的过程中,我们的路由基本上都是定义在controller层的,框架对于 node 原生路由都会进行一层封装,一版都 ...

  5. vue+egg.js+mysql一个前后端分离留言板项目

    一.前序 我相信每个人前端搬运工和我想法都是一样的,都有一个做全栈的梦,无奈面对众多的后台语言,却不从下手,今天由我来带你们潜入全栈的门槛,注意是门槛.能不能学的会后面的内容全靠坚持了. 我今天主要做 ...

  6. springboot项目中接口入参的简单校验

    .katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...

  7. js的replace函数入参为function时的疑问

    近期在写js导出excel文件时运用到replace方法,此处详细的记录下它各个参数所代表的的意义. 定义和用法 replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式 ...

  8. js中函数传参的情况

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  9. (一)将mockjs集成到VUE中后,怎样根据接口入参返回mock结果

    1)安装mockjs,这一步跳过 2)在项目中建立mock模块,笔者的目录结构如下 mock模块与接口模块一一对应,有一个接口,就有一个mock 3)编写登陆模块mock接口,代码如下: import ...

随机推荐

  1. nsqd.go

    }

  2. 深入讨论channel timeout

    深入讨论channel timeout Go 语言的 channel 本身是不支持 timeout 的,所以一般实现 channel 的读写超时都采用 select,如下: select { case ...

  3. AngularJs 服务 广播

    1, angularJs的服务有provider,Service, Factory. Factory是对Service的封装,Service是对Provider的封装. Provide的源码如下: f ...

  4. QTimer在QThread环境中失效的问题

    QTimer在非QThread的环境下能正常工作.但在QThread环境下,需要做一些改动才能正常工作. 创建Qt的线程有两种方式: 1. 子例化QThread 可以在虚函数run中启动定时器,大致的 ...

  5. C#8.0可空引用类型的使用注意要点

    最近VS2019正式版发布了,装下来顺便试用了一下C#8.0,最大的看点应该就是可空引用类型了.不过C#8.0仍然处于Beta的状态,而且试用时也遇到了几个坑. 背景知识说明: 所谓的可空引用类型是指 ...

  6. 大白话5分钟带你走进人工智能-第三节最大似然推导mse损失函数(深度解析最小二乘来源)(1)

                                                    第三节最大似然推导mse损失函数(深度解析最小二乘来源)        在第二节中,我们介绍了高斯分布的 ...

  7. 【Maven篇】---解决Maven线上部署java.lang.ClassNotFoundException和no main manifest attribute解决方法

    一.前述 maven 线上部署的话会出现一些问题比如java.lang.ClassNotFoundException或者no main manifest attribute的话,是因为maven 配置 ...

  8. 审计篇丨PHPcms9.6.3后台XSS审计

    引言 今天与大家分享的文章是关于审计思路的知识点,用到的是PHPcms的最新版本,因为常规扫描无法进入后台,所以我们修改了代码让扫描器爬虫爬到后台. 漏洞复现环境 安装PHPstudy 安装PHPcm ...

  9. 为什么面试你要25K,HR只给你20K?

    周末了,我们来聊个轻松的话题,关于涨薪,哈哈~ 前阵子,栈长给大家分享了<为什么公司宁愿 25K 重新招人,也不给你加到 20K?>,今天我们来聊一个差不多的话题: 为什么面试你要25K, ...

  10. 从壹开始 [ Nuxt.js ] 之二 || 项目搭建 与 接口API

    前言 哈喽大家周一好,今天的内容比较多,主要就是包括:把前端页面的展示页给搭出来,然后调通接口API,可以添加数据,这两天我也一直在开发,本来想一篇一篇的写,发现可能会比较简单,就索性把项目搭建的过程 ...