2024년 9월 24일
// channels.js
const express = require("express");
const router = express.Router();
const conn = require("../mariadb.js");
const { body, validationResult } = require("express-validator");
router.use(express.json());
router
.route("/")
.post(
body('userId').notEmpty().isInt().withMessage('userId는 숫자이어야 해요')
,(req, res) => {
const err = validationResult(req)
if (!err.isEmpty()) {
console.log(err.array());
}
const { name, userId } = req.body;
if (name) {
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(400).json({
message: `요청 값을 다시 보내주세요`,
});
}
});
POSTMAN) POST + localhost:7777/channels + {”name” : “jjong”, “userId” : 3}
POSTMAN) POST + localhost:7777/channels + {”name” : “jjong”, “userId” : abc} → userId 숫자 말고 문자열 (아직 response는 설정 하지 않아서 아무결과가 없음)
// channels.js
const express = require("express");
const router = express.Router();
const conn = require("../mariadb.js");
const { body, validationResult } = require("express-validator");
router.use(express.json());
router
.route("/")
.post(
[body('userId').notEmpty().isInt().withMessage('userId는 숫자이어야 해요'),
body('name').notEmpty().isString().withMessage('name은 문자로 입력해야 해요')]
,(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);
});
});
POSTMAN) localhost:7777/channels + {”name” : “ggung”, “uerId” : “abc”}
POSTMAN) localhost:7777/channels + {”name” : 123, “uerId” : “abc”}
// channels.js
... 생략 ...
conn.query(sql, values, function (err, results) {
if(err) {
console.log(err);
return res.status(400).end();
}
res.status(201).json(results);
});
... 생략 ...
POSTMAN) POST + localhost:7777/users + {”name” : “jjung”, “userId” : 50}
*사용자의 요청이 아닌 부부은 유효성 검사 보다는 우리가 고려해야할 사항임(results.length)
// channels.js
const express = require("express");
const router = express.Router();
const conn = require("../mariadb.js");
const { body, validationResult } = require("express-validator");
router.use(express.json());
router
.route("/")
// 채널 전체 조회
.get(
body('userId').notEmpty().isInt().withMessage('userId는 숫자이어야 해요'),
(req, res) => {
const err = validationResult(req);
if (!err.isEmpty()) {
return res.status(400).json(err.array());
}
const { 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 {
notFoundChannel(res);
}
});
})
POSTMAN) GET + localhost:7777/channels + {”userId” : 2}
POSTMAN) GET + localhost:7777/channes + {”userId” : 20}
// channels.js
const express = require("express");
const router = express.Router();
const conn = require("../mariadb.js");
const { body, param, validationResult } = require("express-validator");
router.use(express.json());
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);
}
});
})
POSTMAN) GET + localhost:7777/channels/3
POSTMAN) GET + localhost:7777/channels/33
POSTMAN) GET + localhost:7777/channels/
그런데 POSTMAN은 localhost:7777/channels/ 을 id값이 url에 들어있어서 채널 개별 조회로 들어 오는 건지, 아니면 채널 전체 조회인데 body값에 userId를 안보낸건지 알 수 없음
단지, location : body에 userId가 없는지에 대한 내용을 알 수 있으므로, 채널 전체 조회가 우선순위인지 알 수 있다.
그럼 왜 채널 조회가 우선순위가 먼저 일까???
: 채널 수정 유효성 검사
// channels.js
const express = require("express");
const router = express.Router();
const conn = require("../mariadb.js");
const { body, param, validationResult } = require("express-validator");
router.use(express.json());
router
.route("/:id")
// 채널 개별 수정
.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 = [id, name]
conn.query(sql, values, function (err, results) {
if (err) {
console.log(err);
return res.status(400).end();
}
res.status(200).json(results);
});
})
POSTMAN) PUT + lcalhost:7777/channels/99 + {”name” : “룰루”} 채널 아이디가 없는 것 수정요청
에러가 나지 않고, response의 body에 affectedRows: 0 확인 → 없는 아이디 수정 요청해서 수정한 건 없다고 함(에러X) _업데이트된건 없음
POSTMAN) PUT + lcalhost:7777/channels/2 + {”name” : “lullu”}
affectedRows: 1 →성공함
// channels.js
... 생략 ...
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);
}
});
})
POSTMAN) PUT + lcalhost:7777/channels/99 + {”name” : “lullu”}
: 채널 삭제 유효성 검사
// channels.js
const express = require("express");
const router = express.Router();
const conn = require("../mariadb.js");
const { body, param, validationResult } = require("express-validator");
router.use(express.json());
... 생략 ...
router
.route("/:id")
.delete(
param("id").notEmpty().isInt().withMessage("채널 id가 필요해요"),
(req, res) => {
const err = validationResult(req); // 채널 id를 입력하지 않으면
if (!err.isEmpty()) {
console.log(err);
return res.status(400).end();
}
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();
}
res.status(200).json(results);
});
}
);
POSTMAN) DELETE + localhost:7777/channels/3
-> affectedRows: 1
-> affectedRows: 0
... 생략 ...
conn.query(sql, id, function (err, results) {
if (err) {
// 없는 채널 id 입력하면
console.log(err);
return res.status(400).end();
}
if (results.affectedRows == 0) {
return res.status(400).end();
} else {
res.status(200).json(results);
}
});
}
);
POSTMAN) DELETE + localhost:7777/channels/70
const err = validationResult(req);
if (!err.isEmpty()) {
console.log(err);
return res.status(400).end();
}
위의 코드가 계속 반복됨
따라서, 함수로 바꿔주자.
// channels.js
const express = require("express");
const router = express.Router();
const conn = require("../mariadb.js");
const { body, param, validationResult } = require("express-validator");
router.use(express.json());
const validate = (req, res) => {
const err = validationResult(req);
if (!err.isEmpty()) {
// userId가 숫자가 아니거나 입력하지 않으면
return res.status(400).json(err.array());
}
}
router
.route("/")
// 채널 전체 조회
.get(
[
body("userId").notEmpty().isInt().withMessage("userId는 숫자이어야 해요"),
validate
],
(req, res) => {
const err = validationResult(req);
if (!err.isEmpty()) {
// userId가 숫자가 아니거나 입력하지 않으면
return res.status(400).json(err.array());
}
const { userId } = req.body;
let sql = `SELECT * FROM channels WHERE user_id = ?`;
conn.query(sql, userId, function (err, results) {
if (err) {
// users에 없는 userId 넣으면
console.log(err);
return res.status(400).end();
}
if (results.length) {
res.status(200).json(results);
} else {
notFoundChannel(res);
}
});
}
)
POSTMAN) GET + localhost:7777/channels + userId 보내지 않음 → 유효성 검사 실패
유효성 검사 잘 작동되는것 학인
POSTMAN) GET + localhost:7777/channels + {”userId” : 4} → 유효성 검사 성공
request가 계속 요청 됨(sending request)→ 에러가 없어서 콜백함수로 넘어가야하지만 못 넘어가고 있음
why ?
vaildate를 미들웨어 형태로 선언해서 일어나는 일임
🍏🍎 오늘의 느낀 점 : 으아아아아,, 점점 더 갈수록 복잡해진다.. 코드는 전보다 줄었지만 더 알아야할 지식이 있으니 더 머리속을 정리하며 익숙해지도록 해야겠다.
express-validator 덕분에 유효성검사를 쉽게 사용할 수 있어서 정말 편리했다. API 우선순위에 대해서도 알게 되고,, 그리고 마지막에 배운 함수를 내부 모듈처럼 쓸 수 있는 것을 배우면서 다시 한번 함수의 편리함을 깨닫게 되고,, 다음 시간에 미들웨어 형태로 선언해서 일어나는 일이 왜 그런지 자세히 알아봐야겠다.