Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Node.js express-validatorを使ってみた

More than 1 year has passed since last update.

expressフレームワークでexpress-validatorを使ってみたので、バリデーションする方法をまとめてみました。

環境

  • MacOSX (10.14)
  • Node.js (v10.15.2)
  • npm (6.4.1)
  • express (4.16.0)
  • express-validator (6.2.0)

準備

まずexpress-validatorをインストールします
npm install express-validator

express-validator概要

できること
+ バリデーション
+ カスタムバリデーション
+ サニタイズ
+ カスタムサニタイズ
+ カスタムエラーメッセージ

バリデーションサンプルコード(ノーマルな使用方法)

まず一番基本的な使い方は以下になります.(公式ドキュメントからコード抜粋)

app.js
const { check, validationResult } = require('express-validator');
// 第二引数にバリデーションの記述
app.post('/user', [
  // checkメソッドを使用してバリデーションを実行
  check('username').isEmail(),
  check('password').isLength({ min: 5 })
], (req, res) => {
// バリデーションの結果にエラーがあるかのチェック
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(422).json({ errors: errors.array() });
  }

  User.create({
    username: req.body.username,
    password: req.body.password
  }).then(user => res.json(user));
});  
  1. ルーティングメソッド(今回はpostファンクション)の第2引数に配列でバリデーションの記述をする。
  2. checkファンクションは全てのreqインスタンスの値から指定したフィールド名に一致するものをバリデーションします。
    bodyの値を対象にしたいならbodyファンクションをクエリパラメータならqueryファンクションを使います。そのほかに種類はあるので公式ドキュメントを見てください(公式ドキュメント)
  3. .isEmail()ファンクションで値がメールアドレスなのかをチェックしています。そのほかにもチェックするためのファンクションがここに記載されているので、見てください。
  4. 第3引数のコールバック関数内にvalidationResultから値を取得し、エラーがあるのかをチェックします。
    エラーがあった場合はHTTPステータスコード422を指定して、レスポンスを返します。

以上がノーマルなバリデーションでの使用方法です。
ただノーマルな使用方法ではルーティングの記述が読みずらくなってしまいます。
そこで次の使用方法が私のおすすめです。

外部ファイル化してすっきりと

ItemRegistValidator.js
const { check } = require('express-validator');

module.exports = [
  check('itemId').not().isEmpty().withMessage('必須項目です。').isInt().withMessage('アイテムIDは数値を入力してください'),
  check('itemName').not().isEmpty().withMessage('必須項目です。'),
];
app.js
const { validationResult } = require('express-validator');

// 外部ファイル化したバリデーション読み込み
const ItemRegistValidator = require('../midleware/validators/itemRegistValidator');
// 第2引数で、バリデーションを実行
router.post('/', ItemRegistValidator, (req, res) => {
// バリデーションの結果にエラーがあるかのチェック
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(422).json({ errors: errors.array() });
  }

  Item.create({
    itemId: req.body.itemId,
    itemName: req.body.itemName
  }).then(item => res.json(item));
});  

バリデーションの記述を外にすることで、だいぶすっきりしました。
バリデーション対象パラメータが多ければ多いほど、外部ファイルにするこの方法がおすすめです。

  1. withMessage()ファンクションはエラーメッセージを任意の内容に指定することができます。
  2. その他に関してはノーマルな使用方法と同様です。'ItemRegistValidator.js'にて配列で、バリデーション処理の記述をし、ルーティングメソッドの第2引数で呼び出します。

バリデーションをカスタマイズ

  // base64でエンコードされた画像ファイルの拡張子をバリデーション
  check('image').custom(image => {
    let extension = image.slice(image.indexOf('/') + 1, image.indexOf(';'));
    if (extension != 'png' && extension != 'jpeg') {
      throw new Error('画像の拡張子はpngまたはjpegを使用してください');
    }
    return true;
  })

validation.jsに用意されていないバリデーションをしたい時customファンクションを使いましょう。
1. customファンクションに引数でコールバック関数を指定し、バリデーションの処理をそのコールバック関数に記述します。
2. エラーであればErrorインスタンスをthrowし、問題なければtrueを返します。

所感

express-validationを使用の仕方を記述いたしました。
上記の内容で、バリデーション処理を記述できるかと思います。
ここには書いていない点もありますので、公式ドキュメントを見てください。
便利な関数が揃っているため非常に書きやすいと思います。

bellcrud
PHPerでフレームワークはCakeとLaravelの経験があります。 趣味でnode.jsとReactを触ってたりします。 週1記事記載を目標にしています。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away