유효성 검사 validation
사용자가 입력한 값에 대한 유효성 (= 타당성)을 검사하는 것
userId : 값이 있어야, 숫자
body('userId').notEmpty().isInt().withMessage('숫자 입력하자!')
채널 name : 값이 있어야, 문자 ->
사람 name : 숫자 X, 문자열, 2자 이상 ...
외부 모듈 express-validator
https://express-validator.github.io/docs/category/guides
express-validator guides | express-validator
📄️ Customizing express-validator If the application you're building is anything but a very simple one, you'll need validators,
express-validator.github.io
npm install express-validator
채널 개별 생성
유효성검사 전 채널 개별 생성
.post((req, res)=>{
const {name, userId} = req.body
if(name && userId){
let sql = `INSERT INTO channels (name,user_id) VALUES (?, ?)`
let values = [name, userId]
conn.query(sql,values,
function(err, results){
res.status(201).json(results)
}
)
} else {
res.status(404).json({
message : "요청 값을 제대로 보내주세요."
})
}
}) // 채널 개별 생성 = db에 저장
수정 후
const {body, validationResult} = require('express-validator')
.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
let sql = `INSERT INTO channels (name,user_id) VALUES (?, ?)`
let values = [name, userId]
conn.query(sql,values,
function(err, results){
res.status(201).json(results)
}
)
}) // 채널 개별 생성 = db에 저장

SQL 에러 처리하기
없은 userId(FK)을 입력했을 경우, 오류 처리가 되지않는 문제를 해결해보자.
conn.query(sql,values,
function(err, results){
if(err){
console.log(err)
return res.status(400).end();
}
res.status(201).json(results)
}
)

마저 정리해보자 ..
채널 전체 조회
.get(
[body('userId').notEmpty().isInt().withMessage('숫자 입력 필요')]
,(req, res)=>{
const arr = validationResult(req)
if(!err.isEmpty()){
return res.status(400).json(err.array())
}
var {userId} = req.body
let sql = `SELECT * FROM channels WHERE user_id = ?`
conn.query(sql, userId,
function(err, results){
if(results.length){
res.status(200).json(results)
}
else {
notFoundChannel(res)
}
}
)
}) // 채널 전체 조회
results.length도 해줄 수 있지 않을까?
-> 유효성 검사는 사용자의 요청에 대한 내용만 처리! 이 부분은 if로 남기는게 맞음.
채널 개별 조회
param 메소드 추가
const {body, param, validationResult} = require('express-validator')
router
.route('/:id')
.get(
param('id').notEmpty().withMessage('채널id 필요')
,(req, res)=>{
const err = validationResult(req)
if(!err.isEmpty()){
return res.status(400).json(err.array())
}
let {id} = req.params
id = parseInt(id)
let sql = `SELECT * FROM channels WHERE id = ?`
conn.query(sql, id,
function(err, results){
if(err){
console.log(err)
return res.status(400).end()
}
if(results.length){
res.status(200).json(results)
}
else {
notFoundChannel(res)
}
}
)
})
채널 개별 수정
.put(
[param('id').notEmpty().withMessage('채널id 필요'),
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);
let {name} = req.body
let sql = `UPDATE channels SET name = ? WHERE id = ?`
let values = [name, id]
conn.query(sql, values,
function(err, results){
if(err){
console.log(err)
return res.status(400).end()
}
if(results.affectedRows == 0){
return res.status(400).end()
} else{
res.status(200).json(results)
}
}
)
}) // 채널 개별 수정
{
"fieldCount": 0,
"affectedRows": 0,
"insertId": 0,
"info": "",
"serverStatus": 2,
"warningStatus": 0,
"changedRows": 0
}
put은 성공, 혹은 실패 상관없이 무조건 results 값을 실행결과로 가져오기때문에
실행결과에서 affectedRows로 검사해줄 수 있음.
채널 개별 삭제
.delete(
[param('id').notEmpty().withMessage('채널id 필요')]
,(req, res)=>{
const err = validationResult(req)
if(!err.isEmpty()){
return res.status(400).json(err.array())
}
let {id} = req.params
id = parseInt(id)
let sql = `DELETE FROM channels WHERE id = ?`
conn.query(sql, id,
function(err, results) {
if(err){
console.log(err)
return res.status(400).end()
}
if(results.affectedRows == 0){
return res.status(400).end()
} else {
res.status(200).json(results)
}
}
);
}) // 채널 개별 삭제
Delete도 PUT과 마찬가지로 성공/실패 상관없이 실행결과 코드를 가져옴
계속 반복되는 코드를 하나로 뽑아내자!
검사 미들웨어 분리
함수일 때에는?
선언부
function validate(req, res) {
const err = validationResult(req)
if(!err.isEmpty()){
return res.status(400).json(err.array())
}
}
호출부
.get(
[body('userId').notEmpty().isInt().withMessage('숫자 입력 필요')]
,(req, res)=>{
validate(req, res)
-> req, res를 그대로 담아주는 데 손수 매개변수로 넣어줘야하는 불편함이 있음.
모듈로 담아주자!
선언부
const validate = (req, res) => {
const err = validationResult(req)
if(!err.isEmpty()){
return res.status(400).json(err.array())
}
}
호출부
router
.route('/')
.get(
[ //콜백함수가 실행되기 전에 할 일을 담아주는 곳
body('userId').notEmpty().isInt().withMessage('숫자 입력 필요'),
validate
]
,(req, res)=>{ ...
❗️여기서 validate는 실행되지만, if(!err.isEmpty())에서 걸리지 않을 시 .get의 이후 코드가 실행되지 않음!
next
const validate = (req, res, next) => {
const err = validationResult(req)
if(!err.isEmpty()){
return res.status(400).json(err.array())
} else {
return next(); // 다음 할 일 (미들 웨어, 함수)
}
}
이렇게 하면 콜백 함수로 넘어감
전체 코드 및 확인 완료
users.js
const express = require('express')
const router = express.Router()
const conn = require('../mariadb')
const {body, param, validationResult} = require('express-validator')
router.use(express.json())
const validate = (req, res, next) => {
const err = validationResult(req)
if(err.isEmpty()){
return next();
} else {
return res.status(400).json(err.array())
}
}
//로그인
router.post(
'/login',
[
body('email').notEmpty().isEmail().withMessage('이메일 확인 필요'),
body('password').notEmpty().isString().withMessage('비밀번호 확인 필요'),
validate
],
(req, res) => {
const {email, password} = req.body
let sql = `SELECT * FROM users WHERE email = ?`
conn.query(sql, email,
function(err, result){
if(err){
console.log(err)
return res.status(400).end()
}
var loginUser = result[0]; //result 없어도 오류 안남!
if(loginUser && loginUser.password == password){
res.status(200).json({
message : `${loginUser.name}님 로그인 되었습니다.`
})
}
else {
res.status(404).json({
message : "이메일 또는 비밀번호가 틀렸습니다."
})
}
}
)
})
router.post(
'/join',
[
body('email').notEmpty().isEmail().withMessage('이메일 확인 필요'),
body('name').notEmpty().isString().withMessage('이름 확인 필요'),
body('password').notEmpty().isString().withMessage('비밀번호 확인 필요'),
body('contact').notEmpty().isString().withMessage('연락처 확인 필요'),
validate
],
(req, res) => {
const {email, name, password, contact} = req.body
let sql = `INSERT INTO users (email, name, password, contact) VALUES(?, ?, ?, ?)`
let values = [email, name, password, contact]
conn.query(sql,values,
function(err, results){
if(err){
console.log(err)
return res.status(400).end()
}
res.status(201).json(results)
}
)
})
//회원 개별 조회
router
.route('/users')
.get(
[
body('email').notEmpty().isEmail().withMessage('이메일 확인 필요'),
validate
]
,(req, res) => {
let {email} = req.body;
let sql = `SELECT * FROM users WHERE email = ?`
conn.query(sql, email,
function (err, results, fields) {
if(err){
console.log(err)
return res.status(400).end()
}
res.status(200).json(results)
}
);
})
.delete( //회원 탈퇴
[
body('email').notEmpty().isEmail().withMessage('이메일 확인 필요'),
validate
]
,(req, res) => {
let {email} = req.body;
let sql = `DELETE FROM users WHERE email = ?`
conn.query(sql, email,
function (err, results, fields){
if(err){
console.log(err)
return res.status(400).end()
}
if(results.affectedRows == 0){
return res.status(400).end()
} else {
res.status(200).json(results)
}
}
)
})
module.exports = router
channels.js
const express = require('express');
const router = express.Router()
const conn = require('../mariadb')
const {body, param, validationResult} = require('express-validator')
router.use(express.json())
const validate = (req, res, next) => {
const err = validationResult(req)
if(err.isEmpty()){
return next(); // 다음 할 일 (미들 웨어, 함수)
} else {
return res.status(400).json(err.array())
}
}
router
.route('/')
.get(
[
body('userId').notEmpty().isInt().withMessage('숫자 입력 필요'),
validate
]
,(req, res, next)=>{
var {userId} = req.body
let sql = `SELECT * FROM channels WHERE user_id = ?`
conn.query(sql, userId,
function(err, results){
if(err) {
console.log(err)
return res.status(400).end()
}
if(results.length){
res.status(200).json(results)
}
else {
return res.status(400).end()
}
}
)
}) // 채널 전체 조회
.post(
[
body('userId').notEmpty().isInt().withMessage('숫자 입력 필요'),
body('name').notEmpty().isString().withMessage('문자 입력 필요'),
validate
]
,(req, res)=>{
const {name, userId} = req.body
let sql = `INSERT INTO channels (name,user_id) VALUES (?, ?)`
let 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)
}
)
}) // 채널 개별 생성 = db에 저장
router
.route('/:id')
.get(
[
param('id').notEmpty().withMessage('채널id 필요'),
validate
]
,(req, res)=>{
let {id} = req.params
id = parseInt(id)
let sql = `SELECT * FROM channels WHERE id = ?`
conn.query(sql, id,
function(err, results){
if(err){
console.log(err)
return res.status(400).end()
}
if(results.length){
res.status(200).json(results)
}
else {
return res.status(400).end()
}
}
)
})
.put(
[
param('id').notEmpty().withMessage('채널id 필요'),
body('name').notEmpty().isString().withMessage('채널명 오류'),
validate
]
,(req, res)=>{
let {id} = req.params;
id = parseInt(id);
let {name} = req.body
let sql = `UPDATE channels SET name = ? WHERE id = ?`
let values = [name, id]
conn.query(sql, values,
function(err, results){
if(err){
console.log(err)
return res.status(400).end()
}
if(results.affectedRows == 0){
return res.status(400).end()
} else{
res.status(200).json(results)
}
}
)
}) // 채널 개별 수정
.delete(
[
param('id').notEmpty().withMessage('채널id 필요'),
validate
]
,(req, res)=>{
let {id} = req.params
id = parseInt(id)
let sql = `DELETE FROM channels WHERE id = ?`
conn.query(sql, id,
function(err, results) {
if(err){
console.log(err)
return res.status(400).end()
}
if(results.affectedRows == 0){
return res.status(400).end()
} else {
res.status(200).json(results)
}
}
);
}) // 채널 개별 삭제
module.exports = router'Devcourse' 카테고리의 다른 글
| <데브코스> 프로젝트2 - Yes24 밴치마킹 (1) | 2026.02.06 |
|---|---|
| [JWT] 쿠키와 세션, JWT 시작하기 (0) | 2026.02.05 |
| <데브코스> 26-02-03 TIL MySQL Workbench 사용, DB 연동, 단축평가 (0) | 2026.02.03 |
| [SQL] DB 실습 - timestamp, 날짜-시간 타입, FK, JOIN (0) | 2026.02.01 |
| <프로그래머스 데브코스 풀스택> 2026-01-30 TIL 데이터베이스(PK, FK, 정규화) (0) | 2026.01.30 |