유효성 검사
사용자가 입력한 값이 유효한 값인지 확인하는 일이다.
예를 들자면 비밀번호가 몇 자리 이상, 연락처에는 문자가 입력될 수 없다 등의 검사를 하는 것이다.
Express 유효성 검사 모듈 설치
우리가 유효성 검사를 하는 모듈을 만들어서 쓸 수도 있지만 Express의 유효성 검사를 해주는 외부 모듈이 있기 때문에 이것을 사용해 보자.
터미널에서 아래 명령어를 입력하여 유효성 검사를 위한 외부 모듈을 설치해 준다.
npm i express-validator
모듈 불러오기
body와 param은 각각 request의 body, param을 의미하고, validationResult는 오류를 받아주는 기능을 한다.
const { body, param, validationResult } = require('express-validator');
채널 전체 조회
http 메서드(get, post, put, delete 등)의 첫 번째 파라미터는 미들웨어이다. 콜백 함수를 실행하기 전에 이 미들웨어부터 실행한다.
사용자가 소유하고 있는 모든 채널을 조회하는 기능이므로 사용자 아이디가 요청으로 들어와야 한다. 따라서 사용자 아이디가 비어있지는 않은지, 정수인지에 대해 유효성 검사를 한다. 두 조건 중 하나라도 만족시키지 않으면 withMessage의 파라미터로 전달되는 문자열이 오류 메시지로 설정된다. 유효성 검사에 대한 결과는 콜백 함수에서 확인한다. 에러가 발생했다면 상황에 맞는 응답을 반환한다.
그리고 SQL문 실행 결과 에러가 발생한 경우에도 상태 코드 400을 응답으로 반환한다.
router.route('/')
.get(body('userId').notEmpty().isInt().withMessage('숫자 입력 필요'),
(req, res) => {
const err = validationResult(req);
if (!err.isEmpty()) {
return res.status(400).json(err.array());
}
const { userId } = req.body;
const sql = `SELECT * FROM channels WHERE user_id = ?`;
conn.query(sql, userId,
function (err, results, fields) {
if (err) {
console.log(err);
return res.status(400).end();
}
if (results.length) {
res.status(200).json(results);
} else {
notFoundChannel(res);
}
}
);
})
채널 생성
2개 이상의 항목에 대해 유효성 검사를 해야 할 때는 배열 안에 작성한다.
사용자 테이블에 존재하지 않는 사용자 아이디에 대해 삽입을 시도하면 외래키 제약 조건에 위배되기 때문에 SQL문 실행 결과에 에러가 발생한다.
router.route('/')
.post(
[body('userId').notEmpty().isInt().withMessage('숫자 입력 필요'),
body('name').notEmpty().isString().withMessage('문자 입력 필요')],
(req, res) => {
const err = validationResult(req);
if (!err.isEmpty()) {
return res.status(400).json(err.array());
}
const { name, userId } = req.body;
const sql = `INSERT INTO channels(name, user_id) VALUES(?, ?)`;
const values = [name, userId];
conn.query(sql, values,
function (err, results) {
if (err) {
console.log(err);
return res.status(400).end();
}
res.status(201).json(results);
}
);
})
채널 개별 조회
url로 전달되는 채널 아이디는 비어있으면 안 되며 숫자여야 한다. 비어있거나 문자인 경우 유효성 검사를 통해 걸러내서 상태 코드 400을 응답으로 보낸다.
router.route('/:id')
.get(param('id').notEmpty().isInt().withMessage('채널 아이디 숫자 필요'),
(req, res) => {
const err = validationResult(req);
if (!err.isEmpty()) {
return res.status(400).json(err.array());
}
let { id } = req.params;
id = parseInt(id);
const sql = `SELECT * FROM channels WHERE id = ?`;
conn.query(sql, id,
function (err, results, fields) {
if (err) {
console.log(err);
return res.status(400).end();
}
if (results.length) {
res.status(200).json(results);
} else {
notFoundChannel(res);
}
}
);
})
채널 개별 수정
수정하고자 하는 채널의 id와 바꿀 새로운 채널명가 request에 적혀있어야 한다. 채널의 id는 숫자여야 하고, 채널명은 문자열이어야 한다.
수정 SQL문 실행 결과, 영향을 받은 행이 없으면 요청으로 받은 id를 가지는 채널이 없다는 것이므로 채널 정보를 찾지 못했다는 메시지를 보낸다.
router.route('/:id')
.put(
[param('id').notEmpty().isInt().withMessage('채널 아이디 숫자 필요'),
body('name').notEmpty().isString().withMessage('채널명 입력 필요')],
(req, res) => {
const err = validationResult(req);
if (!err.isEmpty()) {
return res.status(400).json(err.array());
}
let { id } = req.params;
id = parseInt(id);
const { name } = req.body;
const sql = `UPDATE channels SET name = ? WHERE id = ?`;
const values = [name, id];
conn.query(sql, values,
function (err, results, fields) {
if (err) {
console.log(err);
return res.status(400).end();
}
if (results.affectedRows) {
res.status(200).json(results);
} else {
notFoundChannel(res);
}
}
);
})
채널 개별 삭제
url로 전달되는 채널의 id는 숫자여야 하며, 비어있으면 안 된다.
삭제 SQL문 실행 결과, 영향을 받은 행이 없으면 요청으로 받은 id를 가지는 채널이 없다는 것이므로 채널 정보를 찾지 못했다는 메시지를 보낸다.
router.route('/:id')
.delete(param('id').notEmpty().isInt().withMessage('채널 아이디 숫자 필요'),
(req, res) => {
const err = validationResult(req);
if (!err.isEmpty()) {
return res.status(400).json(err.array());
}
let { id } = req.params;
id = parseInt(id);
const sql = `DELETE FROM channels WHERE id = ?`
conn.query(sql, id,
function (err, results, fields) {
if (err) {
console.log(err);
return res.status(400).end();
}
if (results.affectedRows) {
res.status(200).json(results);
} else {
notFoundChannel(res);
}
}
);
})
검사 미들웨어 분리
모든 라우터에서 유효성 검사에서 에러가 발생했는지 확인하고 있기 때문에 중복되는 코드가 많다. 그리고 유효성 검사에서 에러가 발생했는지 확인하는 부분은 콜백 함수를 실행하기 전에 항상 확인해야 한다. 따라서 공통된 코드를 뽑아내 함수로 만들어준다. 이 항수를 미들웨어로 넣어주는 건 내일 할 예정이다.
const validate = (req, res) => {
const err = validationResult(req);
if (!err.isEmpty()) {
return res.status(400).json(err.array());
}
}
'데브코스' 카테고리의 다른 글
[6주차 - DAY4] cookie, jwt 설정 (0) | 2024.04.04 |
---|---|
[6주차 - DAY3] JWT를 이용한 인증 및 인가 (0) | 2024.04.03 |
[6주차 - DAY1] RESTful API 개발 실습 (0) | 2024.04.01 |
[5주차 - DAY5] Workbench 사용 및 DB 연동 (0) | 2024.03.29 |
[5주차 복습 발표] DB 설계 및 실습 (0) | 2024.03.28 |