Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8909

express-validator を使ってみたポイント

$
0
0

はじめに

以前、 Node.js + Express.jsで Web API を開発した際、 入力チェックに express-validatorを使いました。
express-validator は validator.jsがベースになっており、 validation や sanitize ができる便利なモジュールですが、提供されている API は文字列に対する検証になるため、 JSON パラメータの型を明確にチェックしたい場合には少し注意が必要でした。
今回は使用した際のポイントなんかを自分の整理がてらメモとして残します。

環境

OS: macOS Mojave 10.14.6
Node.js: 10.16.3
Express.js: 4.16.1
express-validator: 6.2.0

Case1(GET & 桁チェック)

引数必須
arg1
arg2min:2 max:4
arg3max:4
arg4min:2
case1.js
constexpress=require('express');constrouter=express.Router();const{check,validationResult}=require('express-validator');router.get('/',validateParam(),async(req,res)=>{consterrors=validationResult(req);if(!errors.isEmpty()){res.status(400).end();return;}res.status(200).end();});functionvalidateParam(){return[check('arg1').exists({checkFalsy:true}).isString(),check('arg2').optional({nullable:true}).isInt().isLength({min:2,max:4}),check('arg3').optional({nullable:true}).isInt().isLength({min:undefined,max:4}),check('arg4').optional({nullable:true}).isInt().isLength({min:2,max:undefined})];}module.exports=router;

OKな例

?arg1=hoge
?arg1=hoge&arg2=12
?arg1=hoge&arg2=1234
?arg1=hoge&arg3=12
?arg1=hoge&arg3=1
?arg1=hoge&arg3=1234
?arg1=hoge&arg4=12
?arg1=hoge&arg4=1234567890

NGな例

?arg1=hoge&arg2=1
?arg1=hoge&arg2=12345
?arg1=hoge&arg3=12345
?arg1=hoge&arg4=1

解説

GET メソッドを例に桁チェックを行います。
桁は isLength()を使用してチェックできます。
さらに、オプションで min (最小値)と max (最大値)が指定できます。
OKな例とNGな例で、オプションで指定した min と max の境界値が効いているのがわかります。

Case2(POST & 型チェック)

引数必須
arg1整数
arg2文字列の整数
arg3真偽値
case2.js
constexpress=require('express');constrouter=express.Router();const{check,validationResult}=require('express-validator');router.post('/',validateParam(),async(req,res)=>{consterrors=validationResult(req);if(!errors.isEmpty()){res.status(400).end();return;}res.status(200).end();});functionvalidateParam(){return[check('arg1').exists({nullable:true}).not().isString().isInt(),check('arg2').optional({nullable:true}).isString().isInt(),check('arg3').optional({nullable:true}).not().isString().not().isInt().isBoolean()];}module.exports=router;

OKな例

{
    arg1: 1,
    arg2: '1'
}

{
    arg1: 1,
    arg3: true    
}

NGな例

{
    arg1: 1,
    arg2: 'a'
}

{
    arg1: 1,
    arg2: 1
}

{
    arg1: 1,
    arg3: 'true'
}

{
    arg1: 1,
    arg3: 1
}

解説

POST メソッドを例に型チェックを行います。
冒頭に触れている通り、 express-validator の API は文字列に対する検証なので、少し工夫をします。
arg1 は整数なので、 .not().isString().isInt()を組み合わせて文字列ではないかつ整数という指定になります。
arg2 のように文字列の整数に限定したい場合は、.isString().isInt()を組み合わせて文字列かつ整数という指定になります。
arg3 は真偽値ですが、文字列の 'false', 'true'や整数の 0, 1が真偽値として判定されないようそれぞれ .not().isString().not().isInt()という指定をしています。ケースによっては上記を真偽値として判定したいという場合もあるので、その場合は適宜指定を外せばOKです。

Case3(POST & 条件付き必須)

引数必須
arg1真偽値
arg2arg1=true の場合のみ必須文字列
case3.js
constexpress=require('express');constrouter=express.Router();const{check,oneOf,validationResult}=require('express-validator');router.post('/',validateParam(),async(req,res)=>{consterrors=validationResult(req);if(!errors.isEmpty()){res.status(400).end();return;}res.status(200).end();});functionvalidateParam(){return[check('arg1').exists({checkNull:true}).not().isString().not().isInt().isBoolean(),check('arg2').optional({nullable:true}).isString(),oneOf([check('arg1').custom((value)=>value===false),check('arg2').exists({checkNull:true})])];}module.exports=router;

OKな例

{
    arg1: false
}

{
    arg1: true,
    arg2: 'hoge'
}

NGな例

{
    arg1: true
}

解説

POST メソッドを例に条件付き必須チェックを行います。
条件付き必須チェックを行う場合には oneOf()が使用できます。
oneOf()は Validation Chain の配列で、いずれか1つでも真であれば検証OK(=すべて偽だった場合に検証NG)となります。これを利用すると、 arg2 のarg1=true の場合のみ必須という条件は、arg1=falsearg2が必須どちらかが真という条件に置き換えることができます(もっとスマートなやり方があれば教えて下さい)。

まとめ

今回は簡単なサンプルを例にとって紹介しましたが、 express-validator のようなモジュールがあると、組み合わせでたいていの要件を満たすことができてとても便利です。
Web API で入力チェックはとても大切ですが、あまり時間をかけたくないところでもあります。また、実装者が複数いれば実装の粒度も変わりやすいので、実装者に依存しにくくなるというのも大きなメリットでしょうか。

今回、使用したコードはGitHubで公開しています。
https://github.com/ponko2bunbun/express-validator-sample


Viewing all articles
Browse latest Browse all 8909

Trending Articles