zoukankan      html  css  js  c++  java
  • Egg.js 中入参的校验

    日常作业中免不了频繁处理 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 的逻辑进行统一。

    相关资源

  • 相关阅读:
    QLU Regular Contest 002 题解
    QLU_ACM 2021 专题训练(一)题解 [暴力、排序、贪心、二分]
    QLU ACM-ICPC 2020 Training Contest 11 @2016 ICPC Dalian [Cloned] 题解
    Codeforces Round #696 (Div. 2) AB题解
    Educational Codeforces Round 102 (Rated for Div. 2) ABCD题解
    20210114
    Codeforces Round #169 (Div. 2) CDE题解
    树剖注意要点
    bzoj3631树链剖分
    bzoj1103树状数组水题
  • 原文地址:https://www.cnblogs.com/Wayou/p/form_validation_in_eggjs.html
Copyright © 2011-2022 走看看