ERD
링크

app.js
const express = require('express');
const commentRouter = require("./routes/comments");
const postsRouter = require("./routes/posts");
const indexRouter = require("./routes/index");
const likeRouter = require("./routes/likes");
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Hello, World!');
});
app.listen(port, () => {
console.log(`${port} 포트로 서버가 열렸습니다.`);
});
app.use(express.json());
app.use("/api", [commentRouter, postsRouter, indexRouter, likeRouter]);
app.use(express.static("static"));
index.js
const express = require("express");
const router = express.Router();
const mysql = require("mysql2");
const bcrypt = require("bcrypt");
const jwt = require('jsonwebtoken');
const pool = mysql.createPool({
host: 'localhost',
user: 'scott',
database: 'tigerdb',
password: 'tiger',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
const connection = pool.promise();
회원가입 API
router.post("/index/join", async(req, res) => {
const nickname = req.body.nickname;
const password = req.body.password;
const passwordCheck = req.body.passwordCheck;
const [rowsNicknameCheck] = await connection.execute(`SELECT NICKNAME FROM USER
WHERE NICKNAME = ?`, [nickname]);
if (rowsNicknameCheck.length) {
res.json({
success: false,
error: "중복된 닉네임입니다."
});
return;
}
const nickname_pattern = /^[a-zA-Z0-9]{3,}$/;
if (!nickname_pattern.test(nickname)) {
res.json({
success: false,
error: "닉네임은 최소 3자 이상, 영문 소문자 또는 대문자, 숫자로만 이루어져야 합니다."
});
return;
}
if (password.length < 4) {
res.json({
success: false,
error: "비밀번호는 4자 이상이어야 합니다."
});
return;
}
if (password === nickname) {
res.json({
success: false,
error: "비밀번호와 닉네임은 달라야 합니다."
});
return;
}
if (password !== passwordCheck) {
res.json({
success: false,
error: "비밀번호와 비밀번호 확인이 일치하지 않습니다."
});
return;
}
const hash = bcrypt.hashSync(password, 10);
const [rowsUser] = await connection.execute(`INSERT INTO USER(NICKNAME, PASSWORD)
VALUES(?, ?)`, [nickname, hash]);
res.json({
success: true,
message: "회원가입이 완료되었습니다."
});
});
login API
router.post('/index/login', async(req, res) => {
const nickname = req.body.nickname;
const password = req.body.password;
const [rows] = await connection.execute(`SELECT PASSWORD, NICKNAME FROM USER
WHERE NICKNAME = ?`, [nickname]);
if (!rows.length) {
res.json({
success: false,
error: "닉네임 또는 패스워드를 확인해주세요."
});
return;
}
const hash = rows[0].password;
if (!bcrypt.compareSync(password, hash)) {
res.json({
success: false,
error: "닉네임 또는 패스워드를 확인해주세요."
});
return;
}
const token = jwt.sign({
"nickname": nickname,
}, 'swJungle', {expiresIn: '7d'});
res.json({
success: true,
token: token
});
});
module.exports = router;
posts.js
const express = require("express");
const router = express.Router();
const mysql = require("mysql2");
const jwt = require('jsonwebtoken');
const pool = mysql.createPool({
host: 'localhost',
user: 'scott',
database: 'tigerdb',
password: 'tiger',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
const connection = pool.promise();
전체 게시글 조회 API
router.get("/posts:page_num", async (req, res) => {
const page = parseInt(req.params.page_num);
const pageSize = 20;
if (!page || page < 1) {
page = 1;
}
const offset = (page - 1) * pageSize;
const [rowsGetAllPost] = await connection.execute(`SELECT * FROM POSTS
ORDER BY created_at DESC LIMIT ?, ?`,[offset, pageSize]);
res.json({
success: true,
result: rowsGetAllPost
});
});
router.get("/posts/post:post_id", async (req, res) => {
const postId = req.params.post_id;
const [rowsPost] = await connection.execute(`SELECT POST.TITLE, POST.POST_CONTENT, POST.POST_NICKNAME,
POST.POST_LIKE, POST.POST_TIME FROM POST
WHERE POST_ID = ?`, [postId]);
res.json({
success: true,
result: rowsPost
});
});
게시글 작성 API
router.post("/posts/write", async(req, res) => {
const title = req.body.title;
const content = req.body.content;
const token = req.headers.authorization;
const decoded = jwt.verify(token, 'swJuingle');
if (!token) {
res.json({
success: false,
error: "로그인이 필요합니다."
});
return;
}
const nickname = decoded.nickname;
const [rowPostData] = await connection.execute(`INSERT INTO POST(TITLE, POST_CONTENT, POST_NICKNAME)
VALUES (?, ?, ?)`, [title, content, nickname]);
res.json({
success: true,
message: "게시글이 등록되었습니다."
});
});
게시글 수정 API
router.put("/posts/update", async(req, res) => {
const postId = req.body.post_id;
const newTitle = req.body.new_title;
const newPost = req.body.new_post;
const token = req.headers.authorization;
const decoded = jwt.verify(token, "swJungle");
if (!token) {
res.json({
success: false,
error: "로그인이 필요합니다."
});
return;
}
const nickname = decoded.nickname;
const [rowsPostCheck] = await connection.execute(`SELECT POST_NICKNAME FROM POST
WHERE POST_ID = ?`, [postId]);
if (rowsPostCheck[0] !== nickname) {
res.json({
success: false,
error: "게시글을 수정할 수 없습니다."
});
return;
}
const [rowsPostUpdate] = await connection.execute(`UPDATE POST SET TITLE = ?, POST_CONTENT = ?
WHERE POST_ID = ?`, [newTitle, newPost, postId]);
if(rowsPostUpdate.affectedRows) {
res.json({
success: true,
message: "게시글 수정이 완료되었습니다."
});
}
});
게시글 삭제 API
router.delete("/posts/delete", async(req, res) => {
const postId = req.body.post_id;
const token = req.headers.authorization;
const decoded = jwt.verify(token, "swJungle");
if (!token) {
res.json({
success: false,
error: "로그인이 필요합니다."
});
return;
}
const nickname = decoded.nickname;
const [rowsPostCheck] = await connection.execute(`SELECT POST_NICKNAME FROM POST
WHERE POST_ID = ?`, [postId]);
if (rowsPostCheck[0] !== nickname) {
res.json({
success: false,
error: "게시글을 삭제할 수 없습니다."
});
return;
}
const [rowsPostDelete] = await connection.execute(`DELETE FROM POST
WHERE POST_ID = ?`, [postId]);
res.json({
success: true,
message: "게시글 삭제가 완료되었습니다."
});
});
module.exports = router;
const express = require("express");
const router = express.Router();
const mysql = require("mysql2");
const jwt = require('jsonwebtoken');
const pool = mysql.createPool({
host: 'localhost',
user: 'scott',
database: 'tigerdb',
password: 'tiger',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
const connection = pool.promise();
댓글 조회 API
router.get("/comments:post_id", async(req, res) => {
const postId = req.params.post_id;
const [rowsGetComments] = await connection.execute(`SELECT COMMENT_NICKNAME, COMMENT_CONTENT, COMMENT_TIME, COMMENT_LIKE
FROM COMMENT WHERE POST_ID = ?`, [postId]);
res.json({
success: true,
result: rowsGetComments
});
});
댓글 작성 API
router.post("/comments/write", async(req, res) => {
const commentContent = req.body.comment_content;
const postId = req.body.post_id;
const token = req.headers.authorization;
const decoded = jwt.verify(token, 'swJuingle');
if (!commentContent) {
res.json({
success: false,
error: "댓글 내용을 입력해주세요."
});
return;
}
if (!token) {
res.json({
success: false,
error: "로그인이 필요합니다."
});
return;
}
const nickname = decoded.nickname;
const [rowsPostComment] = await connection.execute(`INSERT INTO COMMENT(COMMENT_NICKNAME, POST_ID, COMMENT_CONTENT)
VALUES(?, ?, ?)`, [nickname, postId, commentContent]);
res.json({
success: true,
message: "댓글이 등록되었습니다."
});
});
댓글 수정 API
router.put("/comments/update", async(req, res) => {
const commentId = req.body.comment_id;
const newCommentContent = req.body.new_comment_content;
const token = req.headers.authorization;
const decoded = jwt.verify(token, 'swJuingle');
if (!newCommentContent) {
res.json({
success: false,
error: "댓글 내용을 입력해주세요."
});
return;
}
if (!token) {
res.json({
success: false,
error: "로그인이 필요합니다."
});
return;
}
const nickname = decoded.nickname;
const [rowsCommentCheck] = await connection.execute(`SELECT COMMENT_NICKNAME
FROM COMMENT WHERE COMMENT_ID = ?`, [commentId]);
if (rowsCommentCheck[0] !== nickname) {
res.json({
success: false,
error: "댓글을 수정할 수 없습니다."
});
return;
}
const [rowsCommentUpdate] = await connection.execute(`UPDATE COMMENT SET COMMENT_CONTENT = ?
WHERE COMMENT_ID = ?`, [newCommentContent, commentId]);
if(rowsCommentUpdate.affectedRows) {
res.json({
success: true,
message: "댓글 수정이 완료되었습니다."
});
}
});
댓글 삭제 API
router.delete("/comment/delete", async(req, res) => {
const commentId = req.body.comment_id;
const token = req.headers.authorization;
const decoded = jwt.verify(token, 'swJuingle');
if (!token) {
res.json({
success: false,
error: "로그인이 필요합니다."
});
return;
}
const nickname = decoded.nickname;
const [rowsCommentCheck] = await connection.execute(`SELECT COMMENT_NICKNAME FROM COMMENT
WHERE COMMENT_ID = ?`, [commentId]);
if (rowsCommentCheck[0] !== nickname) {
res.json({
success: false,
error: "댓글을 삭제할 수 없습니다."
});
return;
}
const [rowsCommentDelete] = await connection.execute(`DELETE FROM COMMENT WHERE COMMENT_ID = ?`, [commentId]);
res.json({
success: true,
message: "댓글 삭제가 완료되었습니다."
});
});
module.exports = router;
likes.js
const express = require('express');
const router = express.Router();
const jwt = require('jsonwebtoken');
const mysql = require("mysql2");
const pool = mysql.createPool({
host: 'localhost',
user: 'scott',
database: 'tigerdb',
password: 'tiger',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
const connection = pool.promise();
Like 개수 반환 API
router.get('/likes/number:post_id', async(req, res) => {
const postId = req.params.post_id;
const [rowsLikeNumber] = await connection.excute(`SELECT LIKE_NUMBER FROM POST_LIKE
WHERE POST_ID = ?`, [postId]);
if (rowsLikeNumber) {
res.json({
result: rowsLikeNumber
});
} else {
res.json({
result: 0
});
}
});
Like 기능 API
router.post('/likes', async (req, res) => {
const postId = req.body.post_id;
const token = req.headers.authorization;
const decoded = jwt.verify(token, "swJungle");
if (!token) {
res.json({
success: false,
error: "로그인이 필요합니다."
})
return;
}
const nickname = decoded.nickname;
const [rowsLike] = await connection.excute(`SELECT * FROM POST_LIKE
WHERE POST_ID = ? and POST_LIKE_NICKNAME = ?`, [postId, nickname]);
if (rowsLike) {
await connection.excute(`DELETE * FROM POST_LIKE
WHERE POST_ID =? and POST_LIKE_NICKNAME = ?`, [postId, nickname]);
await connection.excute(`UPDATE POST_LIKE SET LIKE_NUMBER = LIKE_NUMBER - 1
WHERE POST_ID = ?` [postId]);
res.json({
success: true,
message: "좋아요를 취소했습니다."
});
} else {
await connection.excute(`INSERT INTO POST_LIKE (POST_ID, POST_LIKE_NICKNAME)
VALUES (?, ?)`, [postId, nickname]);
await connection.excute(`UPDATE POST_LIKE SET LIKE_NUMBER = LIKE_NUMBER + 1
WHERE POST_ID = ?` [postId]);
res.json({
success: true,
message: "좋아요를 눌렀습니다."
});
}
});
module.exports = router;