コントローラーロジックを呼び出す前にExpressルートを検証したいのですが。 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();
}
}
}
次に、validationSchemaを作成し、validateRequest
メソッドを呼び出す派生クラスを作成しました。簡単にするために、「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);
}
}
重要な注意:SchemaLike
を作成するのは、一部のルートにparams, body, query
これは、1回の実行で検証される必要があります。
ルートを呼び出すとき
削除/ users/1
検証は常に失敗します。このエラーが発生する
UnhandledPromiseRejectionWarning:TypeError:joi_1.default.validateは関数ではありません
エラーは、正しく呼び出されたかどうかにかかわらず、すべての検証で発生します。誰かがそれを修正する方法を知っていますか?
express-joi-validation
を使用すると、同じ問題が発生します。
バージョン15を使用しても問題ない場合は、Joiをダウングレードしてください。
npm uninstall --save @hapi/joi
npm install --save @hapi/[email protected]
_joi.validate(request, validationSchema
_を_validationSchema.validate(request
_に変更して修正します。v[16]ではjoi.validate()
がサポートされなくなったためです。 APIドキュメントとリリースノートに明確に記載されています。
Joiの更新バージョンはJoi.validate(req.body,schema);
では機能しません。オブジェクトを個別に使用する必要はありません。これを次のように使用します。それは私のためにスムーズに働きました。私が何か間違っている場合はお知らせください:
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);
// This will send the specify error to the user
res.send(error.details[0].message);
// WORKING WITH DEPRECATED VERSION
// const Validation = Joi.validate(req.body,schema);
// res.send(Validation);
Joi
バージョンをダウングレードする代わりに、最新バージョンのAPIをすばやく確認し、正しい使用方法を確認することをお勧めします。
ここ は、現時点での最新のJoi API(16.1.7)へのリンクであり、validate
の使用例を見ることができます。
また、使用する次のバージョンのlibで何が変更されたかを確認するために、リリースノートを確認することをお勧めします これはJoiバージョン16リリースノートへのリンクです ここで、すべての変更/新機能を確認できます。また、validate
メソッドに関する情報を確認できます。
Joi.validate()およびJoi.describe()を削除(代わりにスキーマで直接呼び出し)(#1941)
以下はスニペットコードで修正されたものです:)
以下のnpmパッケージをインストールします。
npm install --save @hapi/[email protected]
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;
最後に、コントローラーの検証メソッドを呼び出します。
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....
}