AJAX-2 CRUD (23/01/04)

kj_code00·2023년 1월 4일
0

AJAX 방식의 비동기통신 & 서버 분리 & MVC패턴을 적용한 댓글 CRUD 예제코드입니다


1. 디렉토리 구조

프론트 서버 설치 모듈 : express, nunjucks
백엔드 서버 설치 모듈 : express, cors, (cookie-parser)



2. Backend


[server]

const express = require("express");
const cors = require("cors");
const app = express();
const router = require("./routes/index.route");
const cookieParser = require("cookie-parser");

app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(router);

app.use((err, req, res, next) => {
  console.log(err.message);
  res.send(`ERROR ${err}`);
});

app.listen(3000, () => {
  console.log("backend listening on port 3000");
});

[route]

// index
const express = require("express");
const router = express.Router();
const comments = require("../comments/comment.route");

router.use("/comments", comments);

module.exports = router;


// comments
const express = require("express")
const router = express.Router()
const controller = require("./comment.controller")

router.get("/", controller.getComments)
router.get("/:id", controller.getComment)
router.post("/", controller.postComments)
// router.put("/:id", controller.putComments)
router.delete("/:id", controller.deleteComments)

module.exports = router

[repository]

const pool = require("../db.js");

exports.findAll = async () => {
    const [sql] = await pool.query(`SELECT * FROM Comments ORDER by id DESC;`)
    return sql
}

// this.findAll().then(v=>console.log(v))

exports.addComment = async ({ userid, content }) => {
    const sql = `INSERT INTO Comments(userid, content) VALUES('${userid}','${content}')`;
    await pool.query(sql);
};

exports.updateComment = async ({ id, content }) => {
    const sql = `UPDATE Comments SET content = '${content}' WHERE id = '${id}'`;
    await pool.query(sql);
};

exports.deleteComment = async (id) => {
    const sql = `DELETE FROM Comments WHERE id=$'{id}'`;
    await pool.query(sql);
};

  • Controller, Service, Repository는 모두 try & Catch 형태로 작성해야 합니다 (추후 수정 필요!)
  • Controller의 에러 객체는 서버의 에러 출력용 미들웨어로 전달합니다

3. Frontend


프론트엔드 쪽은 클라이언트의 자바스크립트가 할 일이 많아졌네요

요청 메서드와 라우터 경로에 맞게 req.body에 실어보낼 내용을 잘 전달하면 끝!


const commentFrm = document.querySelector("#commentFrm");

const request = ({ method, path, body }) => {
  return new Promise((resolve, reject) => {
    const host = `http://localhost:3000`;
    const xhr = new XMLHttpRequest();
    xhr.open(method, `${host}${path}`);
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.send(JSON.stringify(body));

    xhr.onload = () => {
      if (xhr.readyState === 4 && xhr.status === 200) {
        resolve(JSON.parse(xhr.response));
      } else {
        reject(new Error("Error"));
      }
    };
  });
};

window.addEventListener("load", async () => {
  const comments = await request({
    method: "GET",
    path: "/comments",
  });
  const commentList = document.querySelector("#comment-list");

  for (const comment of comments) {
    const commentRow = document.createElement("li");
    commentRow.innerHTML = `
    <span class="comment-id">${comment.id}</span>
    <span class="comment-userid">${comment.userid}</span>
    <span class="comment-content">${comment.content}</span>
    <span class="comment-register">${comment.register}</span>
    <button class="comment-modify">수정</button>
    <button class="comment-delete">삭제</button>
  `;
    commentList.appendChild(commentRow);
  }

  const submit = document.querySelector(".btn");
  submit.addEventListener("click", async () => {
    const userid = "nazzzo";
    const content = document.querySelector(".int").value;
    await request({
      method: "POST",
      path: "/comments",
      body: { userid, content },
    });
  });
  
  const id = document.querySelector("#comment-id").innerHTML;
  const dltComment = document.querySelector(".comment-delete");
  dltComment.addEventListener("click", async () => {
    await request({
      method: "DELETE",
      path: "/comments/:id",
      body: id,
    });
  });
});

0개의 댓글