[프로그래머스] Node기반 REST API 구현(7)

Lina Hongbi Ko·2024년 10월 10일
0

Programmers_BootCamp

목록 보기
32/76
post-thumbnail

2024년 10월 10일

✏️ 장바구니 테이블 생성

  • 장바구니 테이블에서 user_id 컬럼을 넣어 누가 장바구니에 추가 했는지도 구분하기 위해 만들어준다. (카트 아이템마다 사용자의 아이디를 넣어 그 아이디가 어떤 아이템을 선택했는지 모아서 볼 수 있음) -> user_id가 2인 사람의 장바구니에 카트 아이템 4, 5가 들어있음을 확인

  • cartItem 테이블 생성

  • FK 설정

SQL에 에러가 발생했다 → 121 error

이미 foreign key가 됐던 book_id와 user_id가 다시 한번 foreign key가 된 것임

따라서, foreign key를 만들때는 제약 조건에 이름을 지어야함

  • FK 제약 조건 이름 짓기
    • fk__기준 테이블명__참조테이블명__참조키
      • cartIttmes.user_id → fk_cartItems_users_id

      • likes.user_id → fk_likes_users_id

      • 그런데 또 오류가 생김

      • 테이블에 foreign key을 등록할때마다 그 foreign key가 걸리는 컬럼에 index를 데이터베이스가 알아서 추가하고 있었음(데이터베이스가 내부에서 목차를 셋팅하고 있었음) → 데이터베이스가 자동으로 추가해주는 값 때문임

      • 그래서 이번엔 목차와 likes 테이블의 목차 이름 충돌 발생

    • 에러를 다시 해결해보자 : 에러 1061
      • indexes 탭에 들어가서 cartItems의 index라는 것을 알려줌

  • 이제 값을 INSERT 해보자 -> 장바구니 담기 API를 이제 만들어야함
    • 일단, 테이블 수정부터 (num → quantity로 이름변경 / id :AI 추가)

    • 쿼리문을 일단 살펴보자

      • INSERT INTO cartItems (book_id, quantity, user_id) VALUES (1, 1, 1);

✏️ 장바구니 담기 API 구현

  • 장바구니 담기 API 구현 셋팅
// carts.js

const express = require("express");
const router = express.Router();
router.use(express.json());
const {
  addToCart,
  getCartItems,
  removeCartItem,
} = require("../controller/CartController");

// 장바구니 담기
router.post("/", addToCart);

// 장바구니 아이템 목록 조회
router.get("/", getCartItems);

// 장바구니 도서 삭제
router.delete("/:id", removeCartItem);

// 장바구니에서 선택한 주문 예상 상품 목록 조회
// router.get('/', (req, res) => {
// res.json({'장바구니에서 선택한 주문 예상 상품 목록 조회'});
// });

module.exports = router;
// CartController.js

const conn = require("../mariadb"); // db 모듈
const { StatusCodes } = require("http-status-codes"); // status code 모듈

const addToCart = (req, res) => {
  res.json("장바구니 담기");
};

const getCartItems = (req, res) => {
  res.json("장바구니 아이템 목록 조회");
};

const removeCartItem = (req, res) => {
  res.json("장바구니 도서 삭제");
};

module.exports = { addToCart, getCartItems, removeCartItem };
  • 장바구니에 담으려면 JWT가 필요 → 누군지 알아야 장바구니 담기 가능하니까

// CartController.js

const conn = require("../mariadb"); // db 모듈
const { StatusCodes } = require("http-status-codes"); // status code 모듈

const addToCart = (req, res) => {
  const {book_id, quantity, user_id} =req.body;

  let sql = "INSERT INTO cartItems (book_id, quantity, user_id) VALUES (?, ?, ?)";
  let values = [book_id, quantity, user_id];
  conn.query(sql, values, (err, results) => {
    if (err) {
      console.log(err);
      return res.status(StatusCodes.BAD_REQUEST).end();
    }

    return res.status(StatusCodes.OK).json(results);
  });
};

POSTMAN) POST + localhost:9999/carts + “book_id” : 3, “quantity” : 2, “user_id”: 1}

✏️ 장바구니 목록 조회 API 구현

  • 장바구니 아이템 목록 조회

// CartController.js

const conn = require("../mariadb"); // db 모듈
const { StatusCodes } = require("http-status-codes"); // status code 모듈

const getCartItems = (req, res) => {
  let { user_id } = req.body;

  let sql = `SELECT cartItems.id, book_id, title, summary, quantity, price 
    FROM cartItems LEFT JOIN books 
    ON cartItems.book_id = books.id 
    WHERE user_id = ?`;
  conn.query(sql, user_id, (err, results) => {
    if (err) {
      console.log(err);
      return res.status(StatusCodes.BAD_REQUEST).end();
    }

    return res.status(StatusCodes.OK).json(results);
  });
};

POSTMAN) GET + localhost:9999/carts = { “user_id” : 1 }

  • 장바구니에 아무것도 담기지 않으면 프론트와 나중에 협의해서 장바구니 목록이 비어있다는 것을 어떻게 알려주느냐 협의를 하면 됨

✏️ 장바구니에서 선택한 상품 목록 조회

  • 장바구니 도서 삭제
// CartController.js

const conn = require("../mariadb"); // db 모듈
const { StatusCodes } = require("http-status-codes"); // status code 모듈

const removeCartItem = (req, res) => {
  let { id } = req.params; // cartItemId

  let sql = "DELETE FROM cartItems WHERE id = ?";
  conn.query(sql, id, (err, results) => {
    if (err) {
      console.log(err);
      return res.status(StatusCodes.BAD_REQUEST).end();
    }

    return res.status(StatusCodes.OK).json(results);
  });
};

POSTMAN) DELETE + localhost:9999/carts/6

이랬는데

오래됐다,,

  • 주문 예상 상품 목록 조회

    • 장바구니에서 수량을 수정하면 언제 반영해야할지 생각해봐야하고, 주문하기 누르면 변경된 수량이 주문서 작성에 넘어가야함

    • 그리고 만약 장바구니에서 수량을 수정 했다가 주문하기 안하면 어떻게 할까? 이걸 기억한 걸 보여줘야 하지 않을까? 아니면 기억하지 않고 보여줘야할까?

    • 수량 → 변경이 되면, 페이지 나갔다가 다시 장바구니 페이지에 들어와도 반영되어 있음 으로 생각하고 작업할 예정

      • 수량이 변경되면 DB table cartItems가 업데이트 될 것임
    • 일단 예상 상품 목록들을 보여줘야한다.

      • 그럼 여러개의 데이터가 주어질 때, 어떻게 데이터의 sql select구문을 칠 수 있을까?

      • 쿼리문 -> SELECT * FROM Bookshop.cartItems WHERE user_id = 1 AND id IN (1, 3);

    • 장바구니 목록 조회를 이용해 선택한 장바구니 id를 req body로 요청하면 선택한 상품 목록 조회만 보여주도록 해보자


    • API 설계를 봤을 때, selected된 cartItem들을 넘겨줘야하는데 그럼 이 배열은 어떻게 쿼리로 넘겨줄까?

      • 예전에는 for문 돌려서 배열의 숫자를 변수로 넣어서 적용해줘야 했는데, 현재는 배열을 그대로 넘겨주면 그대로 읽는다고 함
// CartController.js

const conn = require("../mariadb"); // db 모듈
const { StatusCodes } = require("http-status-codes"); // status code 모듈

const getCartItems = (req, res) => {
  let { user_id, selected } = req.body; // selected = [1, 3]

  let sql = `SELECT cartItems.id, book_id, title, summary, quantity, price 
    FROM cartItems LEFT JOIN books 
    ON cartItems.book_id = books.id 
    WHERE user_id = ? AND cartItems.id IN (?)`;
  let values = [user_id, selected];
  conn.query(sql, values, (err, results) => {
    if (err) {
      console.log(err);
      return res.status(StatusCodes.BAD_REQUEST).end();
    }

    return res.status(StatusCodes.OK).json(results);
  });
};

POSTMAN) GET + localhost:9999/carts + {”user_id” : 1, “selected” : [1, 3]}

🍎🍏 오늘의 느낀점 : 오늘은 그전에 해봤던 것들을 바탕으로 실습했어서 스무스하게 넘어갔다. SELECT 구문에서 또 IN을 이용하는 것과 이젠 배열을 그대로 넣어서 사용할 수 있는 것을 배우게 되었다. 그리고 FK 설정을 할 때 만날 수 있는 오류들을 미리 실습해보고 나중에 대비할 수 있을 것 같아서 좋았다.

profile
프론트엔드개발자가 되고 싶어서 열심히 땅굴 파는 자

0개의 댓글