Express Validator - Express

パッケージのインストール

npm install express-validator

express-validator の利用

// express-validator 7 の場合
const { check, validationResult } = require('express-validator');

ルーティングにバリデーションを追加する

「 promiseを使ったMemberApp 」にバリデーションを追加してます。

routes/members.js

var express = require('express');
var router = express.Router();
const pool = require('../db');
const mysql = require('mysql2/promise');
const { check, validationResult } = require('express-validator');

...
...

// レコードの追加
router.get('/add', (req, res, next) => {
  res.render('members/add');
});

// バリデーションの指定
const validator = [
  check('name', '5文字以上10文字以下で入力してください。').isLength({ min: 5, max: 10 }),
  check('age', '整数で入力してください。').isInt(),
];

router.post('/add', validator, (req, res, next) => {
  const errors = validationResult(req);

  if (!errors.isEmpty()) {
    // バリデーションエラーがあった場合の処理
    res.render('members/add', {errors: errors.array()});
    return;
  } else {
    // バリデーションエラーが無かった場合の処理
    let nm = req.body.name;
    let ag = req.body.age;
    let data = { 'name' : nm, 'age' : ag };

    (async () => {
      try {
        const [results, fields] = await pool.query('insert into users set ?', data);
        res.redirect('/');
      } catch (err) {
        console.log(err);
      }
    })();
  }
});

views/members/add.ejs

<!DOCTYPE html>
<html lang="en">
<head>
    <title>MemberApp - Add</title>
    <link rel="stylesheet" href="stylesheets/style.css">
</head>
<body>
    <div id="main">
        <div id="header">
            <h1>Member Add</h1>
        </div>
        <form method="post" action="/add">
          <div class="item">
            <label for="name">名前:<input type="text" name="name" id="name"></label>
            <div class="error-box">
              <% if(typeof errors !== 'undefined') { %>
                <% for(let error of errors){ %>
                  <% if(error.path == "name"){ %>
                    <p><%= error.msg %></p>
                  <% } %>
                <% } %>
              <% } %>
            </div>
          </div>
          <div class="item">
            <label for="age">年齢:<input type="text" name="age" id="age"></label>
            <div class="error-box">
              <% if(typeof errors !== 'undefined') { %>
                <% for(let error of errors){ %>
                  <% if(error.path == "age"){ %>
                    <p><%= error.msg %></p>
                  <% } %>
                <% } %>
              <% } %>
            </div>
          </div>
          <p><input type="submit" value="作成"></p>
        </form>
    </div>
</body>
</html>

errors.array()で得られる内容

errors.array()で得られる配列は次のような内容です。

「 express-validator@7.0.1 」では、name 属性の設定値は「 path 」で取得できます。

[
  {
    type: 'field',
    value: '',
    msg: '5文字以上10文字以下で入力してください。',
    path: 'name',
    location: 'body'
  },
  {
    type: 'field',
    value: '',
    msg: '整数で入力してください。',
    path: 'age',
    location: 'body'
  }
]

Schema-Validation を使う

「 MemberApp サンプル 」で作成したアプリを以下のように編集してください。

routes/members.js

var express = require('express');
var router = express.Router();
const pool = require('../db');
const mysql = require('mysql2/promise');
const { checkSchema , validationResult } = require('express-validator');

router.get('/', function(req, res, next){
  (async () => {
    try {
      const [results, fields] = await pool.query('SELECT * FROM users');
      let data = { users: results };
      res.render('members/index', data);
    } catch (err) {
      console.log(err);
    }
  })();
});

// レコードの追加
router.get('/add', (req, res, next) => {
  res.render('members/add');
});

const validator = checkSchema({
  name: {
    isLength: {
      errorMessage: '5文字以上10文字以下で入力してください。',
      options: { min: 5, max: 10 }
    }
  },
  age: {
    isInt: true,
    errorMessage: '整数で入力してください。'
  }
});

router.post('/add', validator, (req, res, next) => {
  const errors = validationResult(req);

  if (!errors.isEmpty()) {
    // バリデーションエラーがあった場合の処理
    res.render('members/add', {errors: errors.array()});
    return;
  } else {
    // バリデーションエラーが無かった場合の処理
    let nm = req.body.name;
    let ag = req.body.age;
    let data = { 'name' : nm, 'age' : ag };

    (async () => {
      try {
        const [results, fields] = await pool.query('insert into users set ?', data);
        res.redirect('/');
      } catch (err) {
        console.log(err);
      }
    })();
  }
});