[게시판 만들기] TIL 10. Get/veiw/Edit/Delete Post
include
exclude
😀 Notice Board 레파지토리😀
Stack : Javascript, express, nodejs, sequelize
★ : 이번 과정을 통해서 새로 만들어진 파일
☆ : 이번 과정을 통해서 수정된 파일
/
├── 📁/server
│ ├── 📄README.md # Notice_Board README./
├── 📁/server
│ ├── 📄README.md # Notice_Board README.md 파일
│ ├── 📄index.js # node.js로 작성된 웹 서버 진입점
│ ├── 📄package.json
│ ├── 📄package-lock.json
│ ├── 📄.gitignore # node_modules, env 등 포함되지 않게 설정요망
│ ├── 📁/config # 환경변수
│ │ ├── 📄config.js
│ │ └── 📄jwt.js # jwt 관련 환경변수
│ ├── 📁/controllers # 기능 API
│ │ ├── 📄☆ index.js
│ │ ├── 📁User # 유저관련 API
│ │ │ ├── 📄index.js
│ │ │ ├── 📄join.js # join API
│ │ │ ├── 📄login.js # login API
│ │ │ ├── 📄logout.js # logout API
│ │ │ └── 📄withdrawal.js # withdrawal API
│ │ ├── 📁MyPage # 마이페이지 API
│ │ │ ├── 📄index.js
│ │ │ ├── 📄myPage.js # myPage API
│ │ │ └── 📄editUserInfo.js # editUserInfo API
│ │ └── 📁Boards # 게시판 API
│ │ ├── 📄☆ index.js
│ │ ├── 📄writeBoard.js # writeBoard API
│ │ ├── 📄searchBords.js # writeBoard API
│ │ ├── 📄★ getBoards.js # getBoards API
│ │ ├── 📄★ viewBoard.js # viewBoard API\
│ │ └── 📄★ editBoard.js # editBoard API
│ │ └── 📄★ deleteBoard.js # deleteBoard API
│ ├── 📁/middlewares
│ │ ├── 📄CheckEmailForm.js # email 양식이 맞는지 확인하는 middleware
│ │ ├── 📄CheckPassword.js # password 조건이 맞는지 확인하는 middleware
│ │ └── 📄checkToken.js # JWT 검증 middleware
│ ├── 📁/migrations
│ │ ├── 📄20210819052749-create-users.js
│ │ ├── 📄20210819065842-add-column-in-usersTable.js
│ │ ├── 📄20210910065541-create-boards.js
│ │ └── 📄20210910070528-fk-Boards.js
│ ├── 📁/models # DB 모델 파일
│ │ ├── 📄index.js
│ │ ├── 📄users.js
│ │ └── 📄boards.js
│ ├── 📁/routes
│ └── 📄☆ index.js # 분기 파일
│
controllers/Boards/getBoards.js
const { Boards } = require('../../models');
const { Users } = require('../../models');
module.exports = {
get : async (req, res) =>{
Boards.findAll({
order: [['createdAt', 'DESC']],
attributes :{exclude :["content"]},
include : [
{ model : Users,
required: true,
attributes : {exclude :["id","email","password", "salt", "createdAt", "updatedAt"]} }
]
}).then(data => {
res.status(200).send(data)
})
}
}
user API들과 겹치는 부분이 많아 어려운 점은 없었으나, 해당 기능을 작성하면서 include
와 exclude
기능을 사용하였기 때문에 그에 대한 설명을 정리한다.
1. include
와 exclude
controllers/Boards/getBoards.js
const { Boards } = require('../../models');
const { Users } = require('../../models');
module.exports = {
get : async (req, res) =>{
Boards.findAll({
order: [['createdAt', 'DESC']],
attributes :{exclude :["content"]},
include : [
{ model : Users,
required: true,
attributes : {exclude :["id","email","password", "salt", "createdAt", "updatedAt"]} }
]
}).then(data => {
res.status(200).send(data)
})
}
}
13일 자 작성한 코드를 보면서 한가지 놓친 게 있다는 사실 깨달았다. 네이버 카페에서 검색하면 나오는 정보는 포스트 이름, 작성자 이름, 작성 시간, 좋아요나 조회 수, 댓글 개수가 나온다. 댓글 개수는 생각했던 것이 아니니까 Reply API를 만들 때 칼럼을 추가할지 말지에 대해서 고민해보도록 하고. 어제 자로 알아봤던 건 작성자 이름이였고, 오늘 자로 알아본 것은 응답 객체(res)에 불필요한 정보를 덜어내는 것이었다.
1.1 include
공식 레퍼런스 👉 https://sequelize.org/master/manual/eager-loading.html
공식문서에서 보면 Finder 함수는include
절을 사용할 시, SQL문의 Join과 같은 결과를 만든다고 한다. 이 함수의 기본값은 outer join
이기 때문에, 만약 inner join
의 결과를 바란다면, required:true
를 include
절의 옵션에 넣어야 한다. 그리고 where
과 operators 또한 사용할 수 있다고 한다.
const { Boards } = require('../../models');
const { Users } = require('../../models');
module.exports = {
get : async (req, res) =>{
Boards.findAll({
order: [['createdAt', 'DESC']],
include : [{ model : Users}]
}).then(data => {
res.status(200).send(data)
})
}
}
exclude
없는 상태에서 위처럼 코드를 작성할 때 Boards 테이블과 Users 테이블에 있는 모든 데이터가 출력된다. 즉, 불필요한, 혹은 노출되면 안 되는 정보까지 모두 노출된다.
[
{
"id": 2,
"userId" : 1,
"title": "제목입니다1",
"content": "내용입니다2",
"likes": 0,
"createdAt": "2021-08-01T06:02:00.000Z",
"user": {
"id" : 1,
"email" : "assignment@example.com",
"nickname": "팬더",
"password": "abc123",
"slat": "asdfasgda",
"createdAt": "2021-08-01T06:02:00.000Z",
"updatedAt": "2021-08-01T06:02:00.000Z",
}
}
]
위처럼 우리에게 필요한 것은 nickname뿐인데, 다른 데이터도 출력된다. 특히 여기서는 노출되면 안 되는 password와 slat 값이 노출되고 있다.
1.2 exclude
공식 레퍼런스 👉 https://sequelize.org/master/manual/model-querying-basics.html
원래라면 필요한 칼럼만 노출하는 법을 찾았는데, 쉽게 나오지 않아서 불필요한 칼럼은 배제하고 출력할 수 있는 exclude
로 대체했다. 레퍼런스에는 Similarly, it’s also possible to remove a selected few attributes:라고 아주 짧게 설명되어있어서 일단 무작정 시도해보았다.
const { Boards } = require('../../models');
const { Users } = require('../../models');
module.exports = {
get : async (req, res) =>{
Boards.findAll({
order: [['createdAt', 'DESC']],
attributes :{exclude :["content", "updatedAt"]},
include : [
{ model : Users,
required: true,
attributes : {exclude :["id","email","password", "salt", "createdAt", "updatedAt"]} }
]
}).then(data => {
res.status(200).send(data)
})
}
}
Users 테이블에서는 nickname을 빼고 전부 불필요한 데이터이기 때문에 nickname을 제외한 모든 칼럼을 배제했고, Boards 테이블에서는 content 만 필요하지 않다고 판단하여 content 칼럼만 배제하였다.
[
{
"id": 2,
"userId" : 1,
"title": "제목입니다1",
"likes": 0,
"createdAt": "2021-08-01T06:02:00.000Z",
"user": {
"nickname": "팬더",
}
}
]
적용하고나면 위처럼 깔끔하게 출력된다.
2. 고민 중인 것
controllers/Boards/editBoard.js
const { Boards } = require('../../models');
const { Users } = require('../../models');
module.exports = {
put : async (req, res) =>{
const { id } = req.params;
const email = req.user;
const dbUserId = await Users.findOne({
where : {
email
}
}).then(data => data.dataValues.id)
const dbWriterId = await Boards.findOne({
where : {
id
}
}).then(data => data.dataValues.userId)
if(dbUserId != dbWriterId) {
res.status(400).send("You're not the author of this post.");
}
else {
const {title , content} = req.body;
if(!title && !content){
Boards.update({},{
where : { id }
})
.then (data => {
console.log(data)
res.status(200).send(data)
})
}
else if(title && content) {
Boards.update({
title, content
},{
where : { id }
})
.then (data => {
console.log(data)
res.status(200).send(data)
})
}
else {
if (!title) {
Boards.update({
content
},{
where : { id }
})
.then (data => {
console.log(data)
res.status(200).send(data)
})
}
else if (!content) {
Boards.update({
title
},{
where : { id }
})
.then (data => {
console.log(data)
res.status(200).send(data)
})
}
}
}
}
}
포스트 수정 API에 중복되는 부분이 너무 많다…
Boards
.update({
//여기 들어오는 값만 다름.
},{
where : { id }
})
.then (data => {
res.status(200).send(data)
})
정확히는 위 코드가 각 if문에서 겹치고 있는데, 이걸 미들웨어화 하거나, 함수로 만들어서 줄어보고 싶다… ㅜ