码迷,mamicode.com
首页 > 其他好文 > 详细

关于EGG项目添加Joi参数校验解决方案

时间:2019-12-30 11:48:50      阅读:228      评论:0      收藏:0      [点我收藏+]

标签:ams   direct   ring   是什么   script   高度   hapijs   abort   添加   

使用Joi来对egg项目进行参数校验

Joi是什么

Joi?是 hapijs 自带的数据校验模块,高度封装常用的参数校验功能.?Joi文档

项目中引入Joi

将Joi挂载在app对象下,? app.js

const Joi = require('@hapi/joi');
const path = require('path');
class AppBootHook {
    constructor(app) {
        this.app = app;
        const directory = path.join(app.config.baseDir, 'app/validator');
        app.Joi = Joi;
        app.loader.loadToApp(
            directory,
            'validator'
        );
    }
}

module.exports = AppBootHook;

新建Joi校验文件

base_contoller文件下添加Joi拦截

const { Controller } = require('egg');
class BaseController extends Controller {
    constructor(request, response, app) {
        super(request, response, app);
        this.options = {
            //允许存在不在 schema 中的字段
            allowUnknown: true,
            //过滤不存在 schema 中的字段
            stripUnknown: true,
            //可以在检测到第一个错误时立即返回,默认false(检查全部)
            abortEarly: true,
            //可以尝试将值转换为所需的类型(例如,将字符串转换为数字)
            convert: true,
            messages: {
                'any.required': '{{#label}}不能为空',
                'number.base': '{{#label}}参数错误',
                'string.base': '{{#label}}参数错误'
            }
        };
    }
    assert(schema, params) {
        const Joi = this.app.Joi;
        const result = Joi.object(schema).validate(params, this.options);
        if (result.error) {
            throw new Error(result.error.details[0].message);
        }
    }
}

module.exports = BaseController;

添加中间件进行参数拦截校验

/**
 * 统一错误处理
 * @param options {*}
 * @param app
 * @returns {errorHandler}
 */
module.exports = (options, app) => {
    return async function errorHandler(ctx, next) {
        try {
            await next();
        } catch (err) {
            ctx.error = err;
            let message = err.message;
            if (err.status === 500) {
                app.logger.error(err);
                message = err.stack;
                if (app.config.env === 'prod') {
                    message = '服务暂时不可用,正在努力修复中。';
                }
            }
            ctx.status = err.status || 200;
            ctx.body = {
                code: 1,
                message,
                status: ctx.status
            };
        }
    };
};

contorller使用方法

以获取主题列表接口为例

 // 获取主题列表
  this.assert(
      {
        forumId: this.app.Joi.number().required().label('版块ID')
      }, 
 this.ctx.query);

关于EGG项目添加Joi参数校验解决方案

标签:ams   direct   ring   是什么   script   高度   hapijs   abort   添加   

原文地址:https://www.cnblogs.com/Lewiskycc/p/12118577.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!