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

//회원가입 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;
    }

    //비밀번호 hashing
    const hash = bcrypt.hashSync(password, 10);
    
    //DB에 삽입
    const [rowsUser] = await connection.execute(`INSERT INTO USER(NICKNAME, PASSWORD) 
	VALUES(?, ?)`, [nickname, hash]);

    res.json({
        success: true,
        message: "회원가입이 완료되었습니다."
    });

});

login API

//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;
    }
    
    //token 발급
    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

//전체 게시글 조회 API 
//path parameter 방식으로 가져온 페이지에 맞춰서 각 페이지 당 20개의 글을 조회할 수 있게 함
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
    });
});

//게시글 조회 API
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

//게시글 작성 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

//게시글 수정 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

//게시글 삭제 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;

comments.js

const express = require("express");
const router = express.Router();
const mysql = require("mysql2");
const jwt = require('jsonwebtoken');

// const Comment = require("../schemas/comment.js");

const pool = mysql.createPool({
    host: 'localhost',
    user: 'scott',
    database: 'tigerdb',
    password: 'tiger',
    waitForConnections: true,
    connectionLimit: 10,
    queueLimit: 0
});

const connection = pool.promise();

댓글 조회 API

//댓글 조회 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

//댓글 작성 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

//댓글 수정 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

//댓글 삭제 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

//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

//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]);
        //좋아요 개수 - 1
        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]);

        //좋아요 개수 + 1
        await connection.excute(`UPDATE POST_LIKE SET LIKE_NUMBER = LIKE_NUMBER + 1 
	WHERE POST_ID = ?` [postId]);

        res.json({
            success: true,
            message: "좋아요를 눌렀습니다."
        });
    }
});

module.exports = router;
profile
Fear always springs from ignorance.

0개의 댓글

Powered by GraphCDN, the GraphQL CDN