유효성 검사(Validation)란, 사용자가 입력한 데이터 값이 서버의 데이터 값으로 사용하기에 올바른 값인지 검증하는 작업이다.
간단하게 다음과 같은 상황을 생각해볼 수 있다.
"id" : 숫자 라는 데이터를 반드시 요구한다.node.js와 express를 사용한다면, 우리는 npm에서 express-validator 모듈을 이용해서 손쉽게
유효성 검사를 수행할 수 있다.
우선 터미널에서 모듈을 설치한다.
npm install express-validator
그리고, 유효성 검사 처리가 필요한 파일 내에, 외부 모듈로써 불러와준다.
const { body, param, validationResult } = require("express-validator")
단어에서 예상이 가능하겠지만, body는 req.body 값에 대해 유효성 검사를 수행하고,
param은 /:id 와 같은 라우트 파라미터에 대해 유효성 검사를 수행한다.
validationResult는 요청에 대한 검증 결과로, err = validationResult(req)의 형태로 자주 사용된다.
유효성 검사는 특히 if문의 사용을 줄여줄 수 있어서, 코드가 깔끔해진다는 장점이 있다.
사용 예시를 살펴보자.
const express = require("express")
const app = express()
const { body, param, validationResult } = require("express-validator")
app.listen(3000)
app.get("/URL" , [body("id").isInt().notEmpty().withMessage("오류 메시지 칸")] ,
(req,res)=> {
const err = validationResult(req)
if (!err.isEmpty()) {
return res.status(400).json(err.array())
}
res.status(200).end()
})
우선, 유효성 검사를 위한 메소드들은 매우 다양하다.
따라서, 하나의 key값에 여러 방식의 유효성 검사를 수행하고 싶다면 .을 통해 이어주면 된다.
[body("id").isInt().notEmpty().withMessage("오류 메시지 칸")]
대표적으로, 값이 비어있지 않아야하는 notEmpty(),
정수형 자료만 입력받아야하는 isInt(),
유효성 검사에서 에러에 대한 내용을 명시해주는 withMessage("") 등이 있다.
(위 코드에서는 err.array()를 통해 작성한 메시지를 확인할 수 있다.)
위 코드에서는 id 키에 대해서만 유효성 검사를 수행했다.
만약 name이란 키에 대해서도 동시에 유효성 검사를 수행하려면 어떻게 해야할까?
└ 그냥 ,를 이용해 추가로 작성하면 된다.
[
body("id").isInt().notEmpty().withMessage("오류 메시지 칸") ,
body("name").isString().notEmpty().withMessage("오류 메시지 칸")
]
유효성 검사를 수행했을 때, 에러가 발생한 상황에 대해 400 status code를 돌려주기 위해,
if (!err.isEmpty()) {
return res.status(400).json(err.array())
}
해당 구문을 사용했다.
err가 비어있지 않다는 것은 유효성 검사에서 오류를 발견했다는 의미이기 때문에,
return 을 통해 callback함수를 즉각 종료시키고, 클라이언트에게 400 status code를 전달한다.
만약, 유효성 검사에 무사히 통과했다면, if문 아래에 이어지는 코드가 작동될 것이다.
express-validator 와 mysql2 모듈을 같이 사용하게 될 때 주의사항에 대해 알아보자.
아래는 유효성 검사와, 데이터베이스에 INSERT SQL문을 사용하여 데이터값을 삽입하는 코드이다.
app.get("/URL" , [body("id").isInt().notEmpty().withMessage("오류 메시지 칸")] ,
(req,res)=> {
const err = validationResult(req)
if (!err.isEmpty()) {
return res.status(400).json(err.array())
}
conn.query("INSERT INTO myTable (id , name) VALUES (?,?)", [id, name]
, function (err, results) {
res.status(201).json(results)
})
}
})
})
정상적인 값이 들어왔다면, 코드는 유효성 검사를 무사히 마친 후 아래의 conn.query()를 수행한다.
유효성 검사를 무사히 통과했다고 하더라도, 데이터값을 삽입하는 과정에서 오류가 발생할 수 있다.
따라서, query문에서 또한 err에 대한 처리를 해주어야 한다는 점을 주의해야한다.
conn.query("INSERT INTO myTable (id , name) VALUES (?,?)", [id, name]
, function (err, results) {
if (err) {
return req.status(400).end()
}
res.status(201).json(results)
})
INSERT에서는 부적절한 데이터값이 들어왔을 때, 데이터가 삽입되지 않으면서 명확하게 err 를 뱉지만,
UPDATE나 DELETE의 경우는 콜백함수의 err에서 잘 발견되지 않을 수 있다.
예를 들어, conn.query()를 통해 UPDATE,DELETE SQL문을 입력하고, results값을 확인해보면 데이터 수정과 삭제에 실패하더라도 results 값은 기본적으로 다음과 같은 형태를 가지고 있다.

따라서 if(err) 단계에서 검출되지 않기 때문에, 별도의 로직이 필요하다.
예를 들어, 성공적으로 데이터 수정이 완료되면 affectedRows 값은 0이 아닌 값을 가지기 때문이 이를 이용하여 어떤 HTTP status code를 내보내야 할지 설계할 수 있다.