Wecode - Project 3 (부트캠프)/Project 3 과정

Project 3- 주문 api. ->작성 후 수정

JBS 12 2023. 10. 18. 19:38

팁: 작성 시 이렇게 순서대로 틀어놓고 하니 편했음.

 

수정 전

CRUD 에서 

getPosts 

createPosts

updatePosts

deletePosts 하는 거처럼 이렇게 나누어서 했는데, 

orderDao.js

 

orderServices.js
orderController.js

 

orderRouter.js

 

 

controller에서는 하나의 함수 

service에서는 하나의 함수 

dao에서 쫙 작동하게 하는 거라고. 

 

그래서 전격 다시 수정ㅎ.


orderController.js

 

1) orders table 주문 정보 저장

2) orderDetails table 주문 정보 저장

3) 장바구니 삭제  

 

이렇게 했지만,

const createOrders

const createOrderDetails

const DeleteCartsProduct 이렇게 3개로 나누는 게 아니라 

controller는 try - catch 만 다뤄주는 곳 

 

const createOrders 안에 

try  안에 필요한 값들 req.body에서 다 받아오고 

await에서 필요한 값들 (다음 단계로) 다 보내주고 

 

 

 

return 도 하나. 

1) orders table 주문 정보 저장

2) orderDetails table 주문 정보 저장

3) 장바구니 삭제  

각각의 경우에 return 보내주는 게 아니라, 에러를 각각 세분화 해서 보내주는 게 아니라, 


이게 결국엔 연관된 거기에 

안에 넣어주는 것.

 

주문에 저장을 하는 내용으로 연관된 것. 

 

return도, 

됐다 / 안 됐다 

이 둘 중 하나로만.


req.userId = req. body는 아래에 또 들어가 있어서 뺌 

 

 

const createOrders 로 함수는 하나! 

userId는 우리가 req에서 받아온다. 

req.body에서 받아오는 값에 아래 경우 1),2), 3)에서 모두 필요한 값을 [한번에 때려 넣는다] 
       1) orders table 주문 정보 저장
       2) orderDetails table 주문 정보 저장
       3) 장바구니 삭제  


await 는 우리가 다음 layer에 보내주는 값 (다음 layer에서는 async로 받는다. [async ( )] 자리에 들어감)
      orderController.js이기에, orderService.js으로 보내주는 값. 
      [req.body로 controller에서 위에서 받은 값들을 await로 다음 layer로 보내주고, 다음 layer에서는 async로 받는 흐름]

 * controller에서는 req. 로 받고 await로 service로 보내주고,
    service에서 async로 받고, await로 dao에 보내주고,
    dao에서 async로 받고. 

orderRouter.js

그렇기에, orderRouter.js에도 

한줄만 있으면 된다. 

함수는 'createOrders' 하나이기에! 

endpoint router는 소문자가 원칙

orderRouter.js 내에서 선언한   const orderRouter =  
orderRouter는 module.exports 로 내보내주기  module.exports = { orderRouter }; 


orderService.js

전체코드 


뜯어보기

const createOrders 함수 하나 ! 

async 에서 : 받아오는 값에 아래 경우 1),2), 3)에서 모두 필요한 정보를  [한번에 때려 넣는다] 
       1) orders table 주문 정보 저장
       2) orderDetails table 주문 정보 저장
       3) 장바구니 삭제  

if(!product) 부분은 key error ->일단 빼도 됨
여기에 [const updateQuantity = cartQuantity - quantity;] 추가 되어야 함

       1) orders table 주문 정보 저장
                 -> 필요한 정보 : userId, totalPrice, shippingMethod, paymentId를 await로 orderDao로 보낸다. 
       2) orderDetails table 주문 정보 저장
                 -> 필요한 정보 : userId, orderId, productId, quantity 를 await로 orderDao로 보낸다. 
       3) 장바구니 삭제  
                 -> 필요한 정보 : userId,  productId, quantity를 await로 orderDao로 보낸다. 
                 -> 장바구니에서 담은 제품을 삭제 시, userId, 누가 삭제하는지 / productId 어떤 상품을 삭제하는지/ quantity 몇 개를
                      orderId는 주문한 내역에 해당되는거니 상관없어서, 필요없다! 
return deletingCarts (X) 

장바구니에서 제품 삭제 후, respond로 우리가 돌려줄 정보가 없다. 
돌려줄 필요가 없다. 

그래서 return 할 필요가 없다! 

회색 글씨인 건 선언을 안했기 때문인데, 회색이여도 괜찮음 굳이 필요없는 return 필요없음! (정 흰색으로 만들고 싶으면 console.log 찍으면 됨 )

orderService.js '장바구니에서 삭제' 부연설명 

 

1. 장바구니 전체삭제, 부분 삭제 

[ const updateQuantity = cartQuantity - quantity; ]]  추가 되어야 함

장바구니 삭제 [세분화]

if ( 카트의 수량 = order한 수량) {
  Delete 쿼리문 
} else if ( ! 카트 수량 = order 수량) { 
  Update 쿼리문

      --> if ~ else if 일 땐, else  if 뒤에 조건 
      --> 장바구니 전체 삭제 : DELETE
      --> 장바구니 부분 삭제 : UPDATE (부분 삭제 = 수량 변경만 하면 됨)


if ( 카트의 수량 = order한 수량) {
  Delete 쿼리문 
} else 
  Update 쿼리문

      --> if ~ else 일 땐, else  뒤에 조건 안 붙음
      --> 장바구니 전체 삭제 : DELETE
      --> 장바구니 부분 삭제 : UPDATE (부분 삭제 = 수량 변경만 하면 됨)

 

if (조건 ){
}  else   // 조건 없이 

if (조건 ){
}  else if (조건)  {
}

장바구니 전체 삭제 : DELETE
장바구니 부분 삭제 : UPDATE (부분 삭제 = 수량 변경만 하면 됨)

 

 

2. carts 테이블의 quantity 와 orderDetails 테이블에서 quantity 
어떻게 가져올까

carts 의 quantity: '장바구니'에 담긴 제품의 수량 -> 어떤 제품 (productID) , 누가 담은 (userId), 몇 개 (carts 의 quantity)
orderDetails의 quantity: '결제 후 주문내역서'에 담긴 수량 -> 어떤 제품 (productID) , 누가 (userId), 몇 개 (orderDetails quantity)
user_id
product_id, quantity
user_id, product_id, quantity

2-1. orderDetails의 quantity는 위에서부터 내려와서 가져오면 됨 

위에서 async 로 userId, productId, quantity 받아 옴 

2-2. carts 의 quantity는
select 문으로 carts 테이블에서 quantity 가져와야

 --> select  쿼리문은 orderDao.js에 넣고, 

--> orderService.js에는 await로 
       orderDao로 'userId, productId, (orderDetails) quantity' 보내주는 역할 

orderDao는 async로 userId, productID
orderService.js에서 userId, productId를 받아서/ (userId, productId가 같은것을 비교해서) / 수량을 carts 테이블에서 SELECT로 가져온다

그럼, orderDao.js에서 async로 userId, productId 를 받아서,
carts 테이블의 해당 userId, productId를 가진 제품의 quantity를
SELECT 로 가져온다.
(await로 orderDao의 다음 단계인 AppDataSource(DB)로 보내줄거야 = AppDataSource(DB)에서 받아올 거야 ) 

그럼, orderService.js에서 
orderDao.js  의 cartQuantity 함수로부터
await로 userId, productId, quantity를 받는다.  = 

 


추가 알아야 1) 

서로 똑같음   

   const newOrder = await orderDao.createOrders( 

= await orderDao.createOrders( 

 

추가 알아야 2) 

return newOrder (X) 
return newOrderDetails (X) 

장바구니에서 제품 삭제 후, respond로 우리가 돌려줄 정보가 없다. 
돌려줄 필요가 없다. 

그래서 return 할 필요가 없다! 

회색 글씨인 건 선언을 안했기 때문인데, 회색이여도 괜찮음 굳이 필요없는 return 필요없음! (정 흰색으로 만들고 싶으면 console.log 찍으면 됨 )

추가 알아야 3) 

if는 에러 핸들링이기보단

장바구니 수정에서, 
전체 삭제가 아니라, 부분 삭제일 때, 
1개 삭제 시, 

남아있는 수량과 들어온 수량 비교하는 거로, 
만약 같지 않으면 에러, 삭제 안 된다 
이런 형식 

추가 알아야 4) 

 carts 에서 삭제 부분에서

주문 - 결제 - 결제 완료 된 제품 중
장바구니에서 담았으면
장바구니에서 해당 상품 삭제.

구매 경로가
장바구니를 거치지 않는 '바로구매'도 있겠지만,

장바구니에서 결제하는것만 생각하기로)


  ' carts 테이블의 quantity ' 와 

   'orderDetails 테이블의 quantity' 비교

          --> orderDetails 테이블에 quantity 키가 있음. 

 

1)   ' carts 테이블의 quantity ' 와  'orderDetails 테이블의 quantity' 가 같으면   

: 장바구니에 담은 제품 수량과, 실제로 주문내역에서 구매한 제품 수량이 같은 거니까, 

(orderDetails는 결제 후 넘어오는 주문 내역이니까, orderDetails의 quantity는 실제 결제한 수량) 

전체 주문한거니까, 

장바구니에 있던 거 전체 삭제 해도 됨 ( 장바구니에서만 결제하는 거로 가정했기에) 

 

2)   ' carts 테이블의 quantity ' 와  'orderDetails 테이블의 quantity' 가 같지 않으면

: 장바구니에 9개의 제품이 담겼는데, 실제 결제한 주문내역에는 5개 

즉, 장바구니에서 부분 삭제를 해줘야 함. 

 

코드 
  if (cart Quantity == quantity), 전체 삭제
  else , 부분 삭제 


orderDao.js

createOrders 함수 1개고 

async 에서 :  받아오는 값에 아래 경우 1),2), 3)에서 모두 필요한 정보를 [한번에 때려 넣는다] 
       1) orders table 주문 정보 저장
       2) orderDetails table 주문 정보 저장
       3) 장바구니 삭제  
 
const newOrder에 정보들 저장, 

const orderId = newOrder.insertId;
      --> 정보들을 저장한 const newOrder에서  insertId로 자동으로 order.id만 뽑아내는 코드
return orderId;
      --> 뽑아낸 order.id를 orderService.js로 return/ 반환/ 보내주기
       1) orders table 주문 정보 DB에 저장 (INSERT INTO)
                 -> userId, totalPrice, shippingMethod, paymentId

       2) orderDetails table 주문 정보 DB에 저장 (INSERT INTO)
                 -> userId, orderId, productId, quantity 

       3) 장바구니 삭제  ('전체 삭제' 일 경우) 
                 -> userId,  productId, quantity가 같은 것을 삭제 한다. (quantity는 필요없음. userId, product Id 같으면 됨)
                      WHERE user_id = ${userId} AND product_id = ${productId} AND quantity = ${quantity}        
 
                 -> 장바구니에서 삭제 한다.
                      DELETE FROM carts     (DELET FROM 테이블 이름 WHERE 조건 ; 데이터 삭제 sql문) 

                 -> 장바구니에서 담은 제품을 삭제 시, userId, 누가 삭제하는지 / productId 어떤 상품을 삭제하는지/ quantity 몇 개
                      orderId는 주문한 내역에 해당되는거니 상관없어서, 필요없다! 

     4) 장바구니 삭제 ('부분 삭제' 일 경우) 
                 -> userId,  productId 가 같은 것을 삭제 한다.
                      WHERE user_id = ${userId} AND product_id = ${productId}     
 
                 -> carts 테이블의 quantity 칼럼을,  변수 updateQuantity(= cartQuantity - quantity) 로 수정한다 
                     장바구니에 담은 제품 수량 - 주문/결제 한 수량 
                      UPDATE carts SET  quantity = '${updateQuantity}'  

orderDao.js 장바구니 삭제 부분 

cartQuantity로 carts 테이블에서 quantity 가져오기.

가져오는 query문 : select 문 쓰기 

가져온 cartQuantity를 함수에 담아서, 
orderService.js에 보내주기 

 quantity: select로 뽑아오는거라서 한번 더 선언을 해줘야
 
const result = AppDataSource에 모든 테이블들이 있는데, 거기에서 carts 테이블의 quantity를 뽑아온 것!

delete, update는 상관없음. 삭제/ 수정만 하면 끝이니. 
근데 select는 carts 의 quantity를 가져와서 보내줘야 하니까 (return) 

 

select quantity 뽑아온 거 = result라는 배열에 담김.

어짜피 하나 밖에 없을 테니, 객체의 첫 번째 --> result[0] 

거기에서의 quantity라는 키의 값을 뽑아낸다. --> result[0].quantity 


장바구니 전체 삭제
> Delete

장바구니 선택 삭제 
>
선택 삭제라는 것은, 장바구니 테이블의 수량 quantity 칼럼을 Update 하면 됨 (수정) 

 >> 그런데, 장바구니에 5개가 있는데, 주문 결제를 3개 했으면, update quantity = ${quantity} 로 하면, 
장바구니 수량이 3개로 되는 것! 

마이너스를 해야 함! 
쿼리문에서도 마이너스 가능함.
--> orderService.js 에서 [ const updateQuantity = cartQuantity - quantity ] 로 선언! 
--> const updateCarts 에서 변수로 쓰고, await orderDao.updateCarts 로 orderDao.js 로 보내준다! 

 [orderService.js]

 

await는 기다려준다는 뜻!
return을 하지 않아도,

너가 dao로 갔다와,
내가 service에서 기다려줄께!

async 로 받아온다 

 

장바구니 전체 삭제, 부분 삭제  부분 
[orderDao.js] 

 


이후 postman 시도  + 그 전에 거쳐야 할 작업들 

 

Project 3 - [주문 api] postman 통신 시도 **

Postman 모음집 (프론트에 보내는 mock data, api 참고) Postman 모음집 (프론트에 보내는 mock data, api 참고) key 에 해당되는 것은 카멜로 할지 스네이크로 할지 정하면 됨 . value 값은 id에 해당될 때는 " "

pm-developer-justdoit.tistory.com

 

그 전에 거쳐야 할 작업 중에 하나는, 

 

 

middleware 폴더의 
auth.js에서
userId를 블러오게 하는 것  

 

 

middleware 폴더의, auth.js 파일 

   > 토큰을 담아주는 것인데, 

token 에서 불러오게!

 

 

그러면, controller 에서 달라지겠죠?

orderController.js 에서! 

> postman을 활용할 때는 우리팀은 header에  token 없이 가기로 해서 => req.body = userId 

> middleware 활용할 때는 token 관련 코드가 거기에 담겨 있으니까 => req.userId = userId