简体   繁体   English

joi_1.default.validate 不是函数

[英]joi_1.default.validate is not a function

I want to validate my Express routes before calling the controller logic.我想在调用控制器逻辑之前验证我的 Express 路由。 I use joi and created a validator which is able to validate the Request object against the schema object我使用 joi 并创建了一个验证器,它能够根据架构对象验证请求对象

import { Request, Response, NextFunction } from 'express';
import joi, { SchemaLike, ValidationError, ValidationResult } from '@hapi/joi';
import { injectable } from 'inversify';

@injectable()
export abstract class RequestValidator {
    protected validateRequest = (validationSchema: SchemaLike, request: Request, response: Response, next: NextFunction): void => {
        const validationResult: ValidationResult<Request> = joi.validate(request, validationSchema, {
            abortEarly: false
        });

        const { error }: { error: ValidationError } = validationResult;

        if (error) {
            response.status(400).json({
                message: 'The request validation failed.',
                details: error.details
            });
        } else {
            next();
        }
    }
}

Next I created a deriving class which creates the validationSchema and calls the validateRequest method.接下来我创建了一个派生类,它创建了validationSchema 并调用了validateRequest方法。 For the sake of simplicity I will show the "deleteUserById" validation为简单起见,我将展示“deleteUserById”验证

import { Request, Response, NextFunction } from 'express';
import joi, { SchemaLike } from '@hapi/joi';
import { injectable } from 'inversify';

import { RequestValidator } from './RequestValidator';

@injectable()
export class UserRequestValidator extends RequestValidator {
    public deleteUserByIdValidation = async (request: Request, response: Response, next: NextFunction): Promise<void> => {
        const validationSchema: SchemaLike = joi.object().keys({
            params: joi.object().keys({
                id: joi.number().required(),
            })
        });

        this.validateRequest(validationSchema, request, response, next);
    }
}

Important note: I create the SchemaLike that way because some routes might have params, body, query which need to get validated in one run.重要说明:我以这种方式创建SchemaLike ,因为某些路由可能具有需要在一次运行中验证的params, body, query

When calling the Route调用路由时

DELETE /users/1删除 /users/1

the validation always fails.验证总是失败。 I get this error我收到这个错误

UnhandledPromiseRejectionWarning: TypeError: joi_1.default.validate is not a function UnhandledPromiseRejectionWarning: TypeError: joi_1.default.validate 不是函数

The error occurs with every validation, whether called correctly or not.每次验证都会发生错误,无论是否正确调用。 Does someone know how to fix it?有人知道如何解决吗?

您可以通过将joi.validate(request, validationSchema更改为validationSchema.validate(request As joi.validate()在 v16 中不再支持来修复它。它在 API 文档和发行说明中有明确记录。

Update version of joi doesn't work with Joi.validate(req.body,schema); Joi.validate(req.body,schema);更新版本不适用于Joi.validate(req.body,schema); No need to use the object separately.无需单独使用对象。 Use this as following.如下使用。 It Worked for me smoothly.它对我很顺利。 Do let me know if I am wrong at anything:如果我有任何错误,请告诉我:

const Joi = require('@hapi/joi');

const schema = Joi.object({
    name:Joi.string().min(3).required(),
    email:Joi.string().min(4).required().email(),
    password:Joi.string().min(6).required()
});





router.post('/register', async (req,res) => {


    //updated joi
    
   // This is a shorter version
    const { error } = schema.validate(req.body);

    // Error in response

    res.send(error.details[0].message);


    // WORKING WITH DEPRECATED VERSION
    // const Validation = Joi.validate(req.body,schema);
    // res.send(Validation);

Hit the same problem when using express-joi-validation .使用express-joi-validation时遇到同样的问题。

If it's ok for you to use version 15, downgrade Joi will make it.如果您可以使用版本 15,则降级 Joi 即可。

npm uninstall --save @hapi/joi
npm install --save @hapi/joi@15.0.3

I experienced joi.validate() is not a function also.我经历过joi.validate()也不是一个函数。 I checked their documentation and got a fix for it.我检查了他们的文档并得到了修复。

    const Joi = require('@hapi/joi');

const schema = Joi.object({
    name:Joi.string().min(6).required(),
    email:Joi.string().min(6).required().email(),
    password:Joi.string().min(6).required()
});

router.post('/register',  (req, res) => {

    // VALIDATE BEFORE SAVING A USER 
    const Validation = schema.validate(req.body);
    res.send(Validation);

    
})

This works as expected and gives no further error.这按预期工作,不会产生进一步的错误。

You can fix it by changing Joi.validate(request, validationSchema) to validationSchema.validate(request) As Joi.validate() is no longer supported in v16.您可以通过将Joi.validate(request, validationSchema)更改为validationSchema.validate(request)来修复它,因为Joi.validate()不再支持Joi.validate()

For new version对于新版本

const schema = Joi.object({ name: Joi.string() .min(6) .required(),
email: Joi.string() .min(6) .required() .email(),
password: Joi.string() .min(6) .required() });

const validation = schema.validate(req.body);

Instead of downgrading the Joi version it's better to quickly have a look at API of the newest version and check the correct way of using it.与其降级Joi版本,不如快速查看最新版本的API 并检查正确的使用方法。

Here is the link to the latest Joi API at the moment (16.1.7), where you can see an example of using validate .是目前最新的 Joi API 的链接 (16.1.7),您可以在其中看到使用validate的示例。

Also to make sure you know what has been changed in next version of a lib that you use, it is good to have a look at the Release notes, here is a link to a Joi version 16 Release notes where you can see all the changes/new features, and FYI you can see info about validate method:此外,为了确保您知道您使用的下一个版本的 lib 中发生了哪些更改,最好查看发行说明,这里是 Joi 16 版发行说明的链接,您可以在其中查看所有更改/新功能,仅供参考,您可以看到有关validate方法的信息:

Remove Joi.validate() and Joi.describe() (call direct on schema instead) (#1941)删除 Joi.validate() 和 Joi.describe()(改为直接调用架构)(#1941)

For the new version对于新版本

const schema = Joi.object({ name: Joi.string() .min(6) .required(),
email: Joi.string() .min(6) .required() .email(),
password: Joi.string() .min(6) .required() });

const validation = schema.validate(req.body);
res.send(validation);

Here are some fixed with snippet codes :)这里有一些固定的代码片段:)

Install below npm package.安装在 npm 包下面。

npm install --save @hapi/joi@15.0.3

req-validator.js file req-validator.js 文件

const Joi = require("@hapi/joi");

const registerValidation = data => {

const schema = {
    name : Joi.string().min(4).required(),
    email: Joi.string().min(4).required().email(),
    password: Joi.string().min(4).required()
};
return Joi.validate(data,schema);

}
module.exports.registerValidation = registerValidation;

finally, calling the validation method in the controller.最后,调用控制器中的验证方法。

const router = require("express").Router();
const {registerValidation}  = require("./req-validator")

router.post("/register",async(req,res)=> {

const {error} =  registerValidation(req.body);
if(error){
    return res.status(400).send(error.details[0].message);
}
 // logic to save in DB....
}

Simply You can check whether you have @hapi/joi installed and required in your file只需您可以检查您的文件中是否安装并需要@hapi/joi

and for validation use This approach.并用于验证使用此方法。

 const schema= Joi.object().keys({ name: Joi.string().min(6).required(), email: Joi.string().min(6).email(), password: Joi.string().min(6).required() }); const validation = schema.validate(req.body); if(validation.error){ res.status(400).send(validation.error.details[0].message); return ; }

I think This is gonna work我想这会奏效

Following works with the latest version ("@hapi/joi": "^17.1.1"):

    const Joi = require("@hapi/joi");

    const schema = Joi.object({
      name: Joi.string().min(6).required(),
      email: Joi.string().min(6).required().email(),
      password: Joi.string().min(6).required(),
    });
    
  router.post("/register", async (req, res) => {
  const { error } = schema.validate(req.body);

  if (error) {
    res.json({ ErrorMessage: error.details[0].message });
  } else {
    res.json({ message: "valid data" });
  }

});

Create your validate function like this像这样创建您的验证功能

const validateUser = function (user) {
  const schema = Joi.object({
    username: Joi.string().min(5).max(50),
    email: Joi.string().required().email().min(5).max(255),
    password: Joi.string().required().min(5).max(1024),
  });

  return schema.validate(user);
};

You will get the error by你会得到错误

const { error } = validateUser({ email: 'admin' });

And the error message by和错误信息

const message = error.details[0].message;

// Get the instance on schema defination // 获取模式定义上的实例

function validate(model, object, scope) {
  const schema = getSchema(model, scope);
  return schema.validate(object);
}

// actual middleware factory to validate // 要验证的实际中间件工厂

module.exports = function ValidationMiddleware(model, scope) {
  return (req, res, next) => {
    const validationResult = validate(model, req.body, scope);
    if (validationResult.error) {
      throw new Error(validationResult.error.details[0].message);
    } else {
      next();
    }
  };
};

use this用这个

const schema = Joi.object({
    name: Joi.string().min(6).required(),
    email: Joi.string().min(6).email(),
    password: Joi.string().min(6).required()
})

insted of const schema = {...}插入 const 模式 = {...}

and Validate through this:并通过此验证:

const validate = schema.validate(req.body)

instead of Joi.validate(req.body,schema)而不是 Joi.validate(req.body,schema)

Here is something straight out of a project I'm working on, using Joi 17.3.0:这是我正在使用 Joi 17.3.0 进行的项目的直接内容:

PDFCreatorController.exportAsPDF = (req, res) => {
  const data = req.body
  const schema = Joi.object().keys({
    svgDataToExport: Joi.string().required()
  })
  const isValidPromise = new Promise((resolve) => {
    const validation = schema.validate(req.body)
    if (validation.error) {
      res.status(422).json({
        status: 'error',
        message: error,
        data: data
      })
    } else {
      resolve(data)
    }
  })
  isValidPromise.then(inputDataFromUser => {
    try {
      const exportAsPDF = PDFCreatorModel.exportAsPDF(inputDataFromUser)
      exportAsPDF.then(data => {
        res.json(data)
      })
    } catch (error) {
      console.error(error)
      return res.status(500).json(error)
    }
  })
}

Due to Updated version of JOI Package we are all facing this error but here is the solution of that.由于JOI包的更新版本,我们都面临此错误,但这是解决方案。 In Node.js when we facing this error we can solve it applying below solution.在 Node.js 中,当我们遇到此错误时,我们可以应用以下解决方案来解决它。

// Example : Here we try to validate user's data
// User's POST Api 

const schema = Joi.object({
    name: Joi.string().min(1).required(),
    email:  Joi.string().required().email(),
    password: Joi.string().min(8).max(12).required(),
    isEmailVerified: Joi.boolean().required(),
    forgotPasswordToken: Joi.string().required(),
    isDeleted: Joi.boolean().required()
});
try {
    const value = await schema.validateAsync(req.body);
}
catch (err) {
    return res.status(400).send(err);
 }

Lower down the version of joi.降低joi的版本。 to 13.0.1 it will work.到 13.0.1 它将起作用。 in terminal npm i joi@13.0.1.在终端 npm 我 joi@13.0.1。 2.after install check. 2.安装后检查。 dependencies in package.包中的依赖项。 Json file. .json 文件。

npm i joi npm i joi

joi v17.4.x resource: https://joi.dev/api/?v=17.4.2 joi v17.4.x资源: https : //joi.dev/api/ ?v= 17.4.2

const schema = Joi.object({
  email: Joi.string().email().required(),
  password: Joi.string().required().min(5),
});

 const result = schema.validate(YourRequest.body);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM