[node js] 사용자등록, 댓글등록,수정,삭제

seokki kwon·2022년 10월 16일
0

구현기능

  • 사용자 등록
  • 사용자 댓글, 등록, 수정, 삭제

폴더구조


config: sequlize 설정 정보
models: 각 모델이 정의되어 있다.
public:DOM조작 관련 js파일
route: 라우팅 분리
views: 템플릿 파일

사용자등록

  <form id="user-form">
        <fieldset>
          <legend>사용자 등록</legend>
          <div><input id="username" type="text" placeholder="이름"></div>
          <div><input id="age" type="number" placeholder="나이"></div>
          <div><input id="married" type="checkbox"><label for="married">결혼 여부</label></div>
          <button type="submit">등록</button>
        </fieldset>
      </form>

사용자 등록 버튼을 누르면 form 전송이 된다

// 사용자 등록 시
document.getElementById("user-form").addEventListener("submit", async (e) => {
  e.preventDefault();
  const name = e.target.username.value;
  const age = e.target.age.value;
  const married = e.target.married.checked;

  if (!name) {
    return alert("이름을 입력하세요");
  }
  if (!age) {
    return alert("나이를 입력하세요");
  }
  try {
    await axios.post("http://localhost:3001/users", { name, age, married });
    getUser();
  } catch (err) {
    console.error(err);
  }
  e.target.username.value = "";
  e.target.age.value = "";
  e.target.married.checked = false;
});

axios.post('http://localhost:3001/users') post 요청
post 요청을 했으니 서버쪽에서 요청을 받느 라우터를 생성해준다.

app.use("/", indexRouter);
app.use("/users", usersRouter);
app.use("/comments", commentsRouter);

라우팅 파일은 해당형식으로 분리를 하는게 좋다
따로 모듈화를 하지 않는다면 app.js 파일이 매우 길어진다.
users 로 가보자

const express = require("express");
const User = require("../../models/user");
const Comment = require("../../models/comment");

const router = express.Router();

router
  .route("/")
  .get(async (req, res, next) => {
    try {
      const users = await User.findAll();
      res.json(users);
    } catch (err) {
      console.error(err);
      next(err);
    }
  })
  .post(async (req, res, next) => {
    try {
      const user = await User.create({
        name: req.body.name,
        age: req.body.age,
        married: req.body.married,
      });
      res.status(201).json(user);
    } catch (err) {
      console.error(err);
      next(err);
    }
  });

router.get("/:id/comments", async (req, res, next) => {
  try {
    const comments = await Comment.findAll({
      include: {
        model: User,
        where: { id: req.params.id },
      },
    });
    res.json(comments);
  } catch (err) {
    console.error(err);
    next(err);
  }
});

module.exports = router;

express.Router 로 경로를 묶어주었다
경로가 '/' 로 되어있지만 app.js 에서
app.use('/users', usersRouter) 를 해주기 떄문에
경로가 합쳐진다고 이해를 하면 될것같다.

  .post(async (req, res, next) => {
    try {
      const user = await User.create({
        name: req.body.name,
        age: req.body.age,
        married: req.body.married,
      });
      res.status(201).json(user);
    } catch (err) {
      console.error(err);
      next(err);
    }
  });

사용자 등록이 완료되면 201 코드를 반환하며
클라이언트로 user 정보를 json 형식으로 응답해준다.

try 구문에서 문제가 발생한다면
catch로 넘어간다
catch문에서 next(err) 로 에러라우터로 에러 내용을 보내준다.


정의되지 않은 컬럼명을 입력해보니 에러 미들웨어로 이동한다.

사용자 댓글불러오기

사용자 목록의 테이블을 클릭하면
해당하는 사용자의 댓글을 불러온다

 users.map(function (user) {
      const row = document.createElement("tr");
      row.addEventListener("click", () => {
        getComment(user.id);
      });

버튼을 클릭하면 getComment 함수 호출

async function getComment(id) {
  try {
    const res = await axios.get(`/users/${id}/comments`);
    const comments = res.data;
    const tbody = document.querySelector("#comment-list tbody");
    tbody.innerHTML = "";
    comments.map(function (comment) {
      // 로우 셀 추가
      const row = document.createElement("tr");
      let td = document.createElement("td");
      td.textContent = comment.id;
      row.appendChild(td);
      td = document.createElement("td");
      td.textContent = comment.User.name;
      row.appendChild(td);
      td = document.createElement("td");
      td.textContent = comment.comment;
      row.appendChild(td);
      const edit = document.createElement("button");
      edit.textContent = "수정";
      edit.addEventListener("click", async () => {
        // 수정 클릭 시
        const newComment = prompt("바꿀 내용을 입력하세요");
        if (!newComment) {
          return alert("내용을 반드시 입력하셔야 합니다");
        }
        try {
          await axios.patch(`/comments/${comment.id}`, { comment: newComment });
          getComment(id);
        } catch (err) {
          console.error(err);
        }
      });

getComment(id) id를 파라미터로 받아서 서버로부터 get, patch(수정), delete(삭제) 요청을 보낸다.

router.get("/:id/comments", async (req, res, next) => {
  try {
    const comments = await Comment.findAll({
      include: {
        model: User,
        where: { id: req.params.id },
      },
    });
    res.json(comments);
  } catch (err) {
    console.error(err);
    next(err);
  }
});

where 조건으로 해당하는 코멘트만 가져와서 템플릿 페이지로 데이터를 뿌려준다.
include 로 User 정보를 불러왔기에 comment.User.name 으로
user의 이름까지 가져온다 join 을 구현하기 위해서는 모델에서
정의를 따로 해주어야 하는데 이부분은 복습이 필요할듯하다.

데이터를 가져오는 사이클을 한번 정리해보았다
join으로 데이터를 전체적인 사이클은 이해했으나
관계정의 같은 부분은 아직 해보지안아서 할수있을지 모르겠다

응답코드

1xx(정보) : 요청을 받았으며 프로세스를 계속 진행합니다.
2xx(성공) : 요청을 성공적으로 받았으며 인식했고 수용하였습니다.
3xx(리다이렉션) : 요청 완료를 위해 추가 작업 조치가 필요합니다.
4xx(클라이언트 오류) : 요청의 문법이 잘못되었거나 요청을 처리할 수 없습니다.
5xx(서버 오류) : 서버가 명백히 유효한 요청에 대한 충족을 실패했습니다.

2XX : Successful responses

200 OK

요청이 성공적으로 되었습니다. 정보는 요청에 따른 응답으로 반환됩니다.

201 Created

요청이 성공적이었으며 그 결과로 새로운 리소스가 생성되었습니다. 이 응답은 일반적으로 POST 요청 또는 일부 PUT 요청 이후에 따라옵니다.

4XX : Client error responses

400 Bad Request

이 응답은 잘못된 문법으로 인하여 서버가 요청하여 이해할 수 없음을 의미합니다.

401 Unauthorized

비록 HTTP 표준에서는 '미승인(unauthorized)'를 명확히 하고 있지만, 의미상 이 응답은 '비인증(unauthenticated)'를 의미합니다. 클라이언트는 요청한 응답을 받기 위해서는 반드시 스스로를 인증해야 합니다.

402 Payment Required

이 응답 코드는 나중에 사용될 것을 대비해 예약되었습니다. 첫 목표로는 디지털 결제 시스템에 사용하기 위하여 만들어졌지만 지금 사용되고 있지는 않습니다.

403 Forbidden

클라이언트는 콘텐츠에 접근할 권리를 가지고 있지 않습니다. 예를 들어, 그들은 미승인이어서 서버는 거절을 위한 적절한 응답을 보냅니다. 401과 다른 점은 서버가 클라이언트가 누구인지 알고 있습니다.

404 Not Found

서버는 요청받은 리소스를 찾을 수 없습니다. 브라우저에서는 알려지지 않은 URL을 의미합니다. 이것은 API에서 종점은 적절하지만 리소스 자체는 존재하지 않음을 의미할 수 있습니다. 서버들은 인증받지 않은 클라이언트로부터 리소스를 숨기기 위하여 이 응답을 403 대신에 전송할 수도 있습니다. 이 응답 코드는 웹에서 반복적으로 발생하기 때문에 가장 유명할지도 모릅니다.

5XX : Server error reponses

500 Internal Server Error

웹 사이트 서버에 문제가 있음을 의미하지만 서버는 정확한 문제에 대해 더 구체적으로 설명할 수 없습니다.

501 Not Implemented

서버가 요청을 이행하는 데 필요한 기능을 지원하지 않음을 나타냅니다.

502 Bad Gateway

서버가 게이트웨이로부터 잘못된 응답을 수신했음을 의미합니다. 인터넷상의 서버가 다른 서버로부터 유효하지 않은 응답을 받은 경우 발생합니다.

503 Service Unavailable

서버가 요청을 처리할 준비가 되지 않았습니다. 일반적인 원인은 유지보수를 위해 작동이 중단되거나 과부하가 걸린 서버입니다. 이 응답과 함께 문제를 설명하는 사용자 친화적인 페이지가 전송되어야 한다는 점에 유의하십시오. 이 응답은 임시 조건에 사용되어야 하며, Retry-After: HTTP 헤더는 가능하면 서비스를 복구하기 전 예상 시간을 포함해야 합니다. 웹마스터는 또한 이러한 일시적인 조건 응답을 캐시하지 않아야 하므로 이 응답과 함께 전송되는 캐싱 관련 헤더에 대해서도 주의해야 합니다.

504 Gateway Timeout

웹페이지를 로드하거나 브라우저에서 다른 요청을 채우려는 동안 한 서버가 액세스하고 있는 다른 서버에서 적시에 응답을 받지 못했음을 의미합니다. 이 오류 응답은 서버가 게이트웨이 역할을 하고 있으며 적시에 응답을 받을 수 없을 경우 주어집니다. 이 오류는 대게 인터넷상의 서버 간의 네트워크 오류이거나 실제 서버의 문제입니다. 컴퓨터, 장치 또는 인터넷 연결에 문제가 아닐 수 있습니다.

출처:https://www.whatap.io/ko/blog/40/

profile
웹 & 앱개발 기록

0개의 댓글