프로젝트 이모저모/HoduMarket 프로젝트

오픈마켓 프로젝트) 장바구니에서 상세 상품 정보 불러오기

Ella Seon 2023. 5. 15. 11:19

이번에는 버그라기 보다는..몇일 째 고민을 해도 떠오르지 않아서 헤맸던 로직을 정리하고자 한다.

 

0. 문제 

- 장바구니를 불러오는 api 를 통신했는데, 장바구니 아이템의 응답값이 아래처럼 나와있었다.

나는 화면에 장바구니의 상품목록을 장바구니 페이지에 렌더링 해야하는데, 

장바구니를 불러오는 api 의 응답값에는 상품 상세정보(상품 가격, 상품 이미지, 상품명 등등) 가 아니라 단순히 장바구니 정보 들만 나와있었다.

 

그러면...상품 상세정보를 어떻게 불러와야하지...

계속 고민에 빠졌었다.

1. 문제  해결 과정

- 초반에 생각한 방향은 상품 목록을 가져오는 별도의 API 가 있다면 이 API 를 사용해서 상품 정보를 가져오고,

장바구니에 있는 상품과 일치하는 상품정보를 렌더링 하는 것이었다.

 

하지만 이것을 코드로 어떻게 구현할지가...머릿속이 막막했다. 

1) 모든 상품 상세 정보 불러와서 장바구니 product_id 와 비교하기

먼저 상품 상세정보를 불러오는 api 를 다시 cartListSlice 에 적었다.  이미 productSlice 에서 아래처럼 불러왔었는데 또 cartSlice.tsx에 불러오기로 했다. productSlice.tsx에서는 페이지 네이션을 하느라 전체상품을 못불러오고 페이지별로 상품을 불러오기에 전체상품정보를 불러오는 로직이 필요했었다. 

// productSlice.ts

export const fetchGetProducts = createAsyncThunk(
  "products/fetchGetProducts",
  async (currentPage: number) => {
    try {
      const products = await axios.get(
        `${BASE_URL}/products?page=${currentPage}`
      );
      // console.log(products.data);
      return products.data;
    } catch (error: any) {
      console.log(error);
    }
  }
);

 

그래서 cartSlice.tsx 에  장바구니 상품 목록을 불러오는 api 와 상품 상세 정보를 불러오는 api 를 작성했다.

// 장바구니 상품 정보 가져오기
export const fetchGetCartList = createAsyncThunk(
  "cartList/fetchGetCartList",
  async (TOKEN: string) => {
    try {
      const config = {
        headers: {
          Authorization: `JWT ${TOKEN}`,
        },
      };
      let result = await axios.get(`${BASE_URL}/cart/`, config);
      console.log(result.data);
      return result.data;
    } catch (error: any) {
      console.log(error);
    }
  }
);

// 상품 상세 정보 불러오기
export const fetchGetAllProducts = createAsyncThunk(
  "products/fetchGetAllProducts",
  async () => {
    try {
      const products = await axios.get(`${BASE_URL}/products/`);
      // console.log(products.data);
      return products.data;
    } catch (error: any) {
      console.log(error);
    }
  }
);

 

하지만, 결론적으로 이 방법은 쓸 수가 없었다.

모든 상품을 불러올줄 알았떤 fetchGeteAllProducts의 응답값은... 15개 밖에 불러오지 못했다..ㅠㅠㅠ

api 를 제대로 확인하지 못한 내 불찰이었다.

전체 상품을 못불러오는데...어떻게 장바구니 상품의 product_id 와 상품상세정보의 product_id 를 비교해서 상품 상세정보를 빼오지...? ㅠㅠ

 

하긴 심지어...모든 상품정보를 불러와서 맞는것만 cartItems 에 넣는다는 것이 로직상은 괜찮을지 모르나...

모든 상품정보를 불러오는거 자체가 우선... 상품이 많은 경우 응답이 느려지거나 네트워크 부하가 발생할 수 있다는 것을 왜 몰랐을까....그러니 서버개발자 분도 애초에 최대 15개 상품만 가져올수 있도록 설정해놨겠지...? ㅠㅠ

 

2) 장바구니 응답값인 product_id  를 이용해서 상품 개별정보를 불러오는 API 에 적용해보자

 useEffect(() => {
    if (TOKEN) {
      dispatch(fetchGetCartList(TOKEN));
    }
  }, [TOKEN, dispatch]);

  useEffect(() => {
    cartItems.forEach((cartItem) => {
      dispatch(fetchGetProductDetail(cartItem.product_id));
    });
  }, [cartItems, dispatch]);

 

다행히 장바구니에 잘 불러와졌다.

 

하지만, 이 방법이 과연 좋을까 의문이 있다.

1️⃣ 효율성 문제 : 각 상품 아이디에 대해 별도의 HTTP 요청을 수행하면, 네트워크 오버헤드가 커질 수 있을 것 같다.
특히, 장바구니에 많은 수의 아이템이 있을 경우, 성능저하가 발생할것이다.  
2️⃣ 서버 부담 : 각각의 상품 아이디에 대해 별도의 요청을 보내면, 서버에 많은 부담을 줄수 있을것이다. 서버에 많은 부담을 줄 수 있다. 

 

결론은, 백엔드 API 를 수정해서 한번의 요청으로 여러 상품의 상세정보를 한번에 받아 올 수 있게해야하는데,

나는 주어진 백엔드 API 로만 사용하다보니... 고칠 수가 없다 ㅠㅠㅠㅠㅠ

이래서 풀스택을 하라는건가 싶기도 하다