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

Lina Hongbi Ko·2024년 10월 11일
0

Programmers_BootCamp

목록 보기
33/76
post-thumbnail

2024년 10월 11일

✏️ 주문 API

  • 구현해야할 것 : 결제하기 = 주문하기 = 주문 등록 = 데이터베이스 주문 insert & 장바구니에서 주문된 상품은 delete 되야함

  • 주문 API 구현 셋팅
// orders.js

const express = require("express");
const router = express.Router();
const {
  order,
  getOrders,
  getOrderDetail,
} = require("../controller/OrderController");
router.use(express.json());

// 주문 하기
router.post("/", order);

// 주문 목록(내역) 조회
router.get("/", getOrders);

// 주문 상세 조회
router.get("/:id", getOrderDetail);

module.exports = router;
// OrderController.js

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

const order = (req, res) => {
  res.json("주문 하기");
};

const getOrders = (req, res) => {
  res.json("주문 목록(내역) 조회");
};

const getOrderDetail = (req, res) => {
  res.json("주문 상세 상품 조회");
};

module.exports = { order, getOrders, getOrderDetail };
  • DB ERD

  • DB 생성

    • delivery, orders, orderedBook 테이블 생성

    • FK 설정

    • FK 제약 조건 이름 짓기 -> 나만의 약속(규약)을 통해 만들 것 _ 컨벤션

  • delivery 테이블에 데이터 insert
    => 배송 정보 입력 : INSERT INTO delivery (address, receiver, contact) VALUES (”서울시 중구”, ”김영희“, “010-1234-5678”)

  • orders 테이블에 데이터 insert
    => 주문 정보 입력 : INSERT INTO orders (book_title, total_quantity, total_price, user_id, delivery_id) VALUES (”book1”, 3, 60000, 1, 1);

  • orderedBook 테이블에 데이터 insert
    => 상세 주문 정보 입력 :
    INSERT INTO orderedBook (order_id, book_id, quantity) VALUES (1, 1, 1);
    INSERT INTO orderedBook (order_id, book_id, quantity) VALUES (1, 3, 2);

✏️ insertId

  • 방금 insert한 데이터 PK 가져오는 방법

    • LAST_INSERT_ID() : 시간차 공격 >> 이전 값을 들고 옴 → 세션이 섞이면 오류남

      • SELECT last_insert_id();
    • MAX() → id가 max인 값을 가져오면 가장 최신의 데이터를 가져오겠지 → 이 방법 더 추천

      • SELECT max(id) FROM Bookshop.orderedBook;
  • 주문을 할 때 → 배송 정보 입력 후 → 주문 정보 입력하는데, delivery_id를 최신값으로 넘겨줘야 입력한 배송 정보 줄 수 있음
    • INSERT INTO orders (book_title, total_quantity, total_price, user_id, delivery_id) VALUES (”book1”, 3, 60000, 1, (SELECT max(id) FROM delivery));
  • 그리고 주문 정보 입력 후 → 주문 상세 목록 조회를 하는데, order_id를 최신값으로 넘겨줘야 그 주문의 상세 목록을 볼 수 있지
    • INSERT INTO orderedBook (order_id, book_id, quantity) VALUES ((SELECT max(id) FROM orders), 1, 1);

✏️ Order API 구현

(1), (2), (3)의 순서에 따라 차근차근 구현해보자

💡 delivery insert

// OrderController.js

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

const order = (req, res) => {
  const { items, delivery, totalQuantity, totalPrice, userId } = req.body;

  let sql =
    "INSERT INTO delivery (address, receiver, contact) VALUES (?, ?, ?)";
  // const delivery_id = "SELECT max(id) FROM delivery";
  let values = [delivery.address, delivery.receiver, delivery.contact];
  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/orders + { “delivery” : {”address” : “인천시 중구”, “receiver” : “김나리”, “contact” : “010-2222-2222”}}

결과를 보면 ‘insertId : 2’ 를 볼 수 있다 → PK의 값임!

그래서 우리는 굳이 select구문 넣지 않고, insertId를 이용할 예정임

// OrderController.js

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

const order = (req, res) => {
  const { items, delivery, totalQuantity, totalPrice, userId } = req.body;
	let delivery_id;
	
  let sql =
    "INSERT INTO delivery (address, receiver, contact) VALUES (?, ?, ?)";
  // const delivery_id = "SELECT max(id) FROM delivery";
  let values = [delivery.address, delivery.receiver, delivery.contact];
  conn.query(sql, values, (err, results) => {
    if (err) {
      console.log(err);
      return res.status(StatusCodes.BAD_REQUEST).end();
    }
    
    delivery_id = results.insertId
    
    return res.status(StatusCodes.OK).json(results);
  });
};

💡 orders insert

  • delivery id 넘겨주는건 일단 저렇게 넘겨준다고 생각해서 이미 데이터 2가 들어왔다는 가정을 하고 (1),
  • (2)에 들어갈 데이터를 쿼리 요청 해야하는데 대표책제목을 어떻게 가져올까?
    • 선택한 장바구니 상품 목록 조회에서 받은 값을 이용해서 줄 것임
    • 그리고 대표 도서 제목 하나만 보내 달라고 할 예정
  • 그리고 order id 또한 insertId를 이용할 예정
// OrderController.js

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

const order = (req, res) => {
  const { items, delivery, totalQuantity, totalPrice, userId, firstBookTitle } =
    req.body;
  let delivery_id = 2;
  let order_id;

  let sql =
    "INSERT INTO delivery (address, receiver, contact) VALUES (?, ?, ?)";
  let values = [delivery.address, delivery.receiver, delivery.contact];
  // conn.query(sql, values, (err, results) => {
  //   if (err) {
  //     console.log(err);
  //     return res.status(StatusCodes.BAD_REQUEST).end();
  //   }

  //   delivery_id = 2; // results.insertId;

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

  sql = `INSERT INTO orders (book_title, total_quantity, total_price, user_id, 
  delivery_id) VALUES (?, ?, ?, ?, ?)`;
  values = [firstBookTitle, totalQuantity, totalPrice, userId, delivery_id];
  conn.query(sql, values, (err, results) => {
    if (err) {
      console.log(err);
      return res.status(StatusCodes.BAD_REQUEST).end();
    }

    order_id = results.insertId;
    console.log(order_id);

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

POSTMAN) POST + localhost:9999/orders + { “delivery” : {”address” : “인천시 중구”, “receiver” : “김나리”, “contact” : “010-2222-2222”}, “firstBookTitle” : “book3”, “totalQuantity” : 2, “totalPrice” : 40000, “userId” : 1}

💡 orderedBook insert

  • 이제 (3)번 차례인 orderedBook에 데이터를 insert해보자
  • 이중 배열을 이용해 벌크로(묶음/번들/복수개의 데이터를 한번에 움직임) 인서트를 할 수 있음 ⇒ [values]
// OrderController.js

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

const order = (req, res) => {
  const { items, delivery, totalQuantity, totalPrice, userId, firstBookTitle } =
    req.body;
  let delivery_id = 2;
  let order_id = 2;

 //(1) delivery에 Insert
  let sql =
    "INSERT INTO delivery (address, receiver, contact) VALUES (?, ?, ?)";
  let values = [delivery.address, delivery.receiver, delivery.contact];
  // conn.query(sql, values, (err, results) => {
  //   if (err) {
  //     console.log(err);
  //     return res.status(StatusCodes.BAD_REQUEST).end();
  //   }

  //   delivery_id = 2; // results.insertId;

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

  // (2) order에 Insert
  sql = `INSERT INTO orders (book_title, total_quantity, total_price, user_id, delivery_id) VALUES (?, ?, ?, ?, ?)`;
  values = [firstBookTitle, totalQuantity, totalPrice, userId, delivery_id];
  // conn.query(sql, values, (err, results) => {
  //   if (err) {
  //     console.log(err);
  //     return res.status(StatusCodes.BAD_REQUEST).end();
  //   }

  //   order_id = results.insertId;
  //   console.log(order_id);

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

  // (3) orderedBook에 Insert
  sql = `INSERT INTO orderedBook (order_id, book_id, quantity) 
  VALUES ?`;

  // items ... 배열 : 요소들을 하나씩 꺼내서 foreach문을 돌려서 값을 꺼내 values를 만들고 sql을 던져야함
  values = [];
  items.forEach((item) => {
    values.push([order_id, item.book_id, item.quantity]);
  });
  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/orders + {"items: [{"book_id" : 5, "quantity" : 1}, {"book_id" : 7, "quantity" : 1}]", "delivery" : ~~~ 생략}

🍏🍎 오늘의 느낀점 : 오늘은 insertId를 이용해서 쉽게 insert했던 최신의 값을 넣어주는 것을 배워서 나중에 유용하게 써먹을 것 같다는 생각을 했다. 그리고 API 설계와 erd를 계속 수정하면서 데이터를 어떻게 전해주면 좋을까 하는 생각들을 음,, 로직이겠지? 하는게 중요하겠구나 하는 생각이 역시 또 들었다.

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

0개의 댓글