본문 바로가기
개발 기초 다지기

배달 메뉴 목록 정렬 기능 구현(같은 카테고리에서 낮은 가격 순으로)

by 너의고래 2024. 6. 20.
반응형

이번 팀프로젝트를 진행하며 항상 그렇지만 수많은 에러에 마주했다. 정리해야할 글이 많은데 오늘은 복잡할줄 알았는데 의외로 간단했던(?) 배달 메뉴 목록 정렬에 대해 정리해보려한다.

 

메뉴 목록 정렬은 어떻게 진행하는게 좋을까?

메뉴 목록 조회를 구현하던 중 든 생각이다. 이전에는 이 부분에 대해 명시되어있었는데, 이번 프로젝트는 자유도가 조금 더 있는 편이다보니 고민이 시작됐다. 팀프로젝트인 만큼 팀원들과 대화를 나눠보았다. 

 

(1) 카테고리 별 구성

우선 우리는 메뉴 타입을 body로 받고있었다. 이것을 통해 다른 배달어플들처럼 각 메뉴의 카테고리별로 유저들에게 보였으면 하는 마음이 들었다. 우리는 메뉴 타입을 '메인', '사이드', '음료' 이렇게 세가지로 나누었다.

 

(2) '메인' -> '사이드' -> '음료' 순으로 정렬

다른 배달 어플들처럼 이 카테고리 순서대로 보여졌으면 하는 마음이 들었다. 운이 좋게도 이름 순서대로 정렬해도 저 순서대로이긴 하지만 만약 다른 카테고리가 추가되거나, 카테고리 이름이 수정된다면 불상사이다.

그렇게 고민하다가 menuType을 '숫자'로 받기로 했다. 이렇게하면 오름차순 시 '1:메인', '2:사이드', '3:음료'로 정렬할 수 있었다.

 

(3) 카테고리 안에서의 정렬

사실 팀원들과는 카테고리 정렬까지만 이야기 나누었지만, 이 안에서도 정렬이 있었으면 하는 마음에 price를 오름차순으로 정렬해주었다.

 

(4) 조회시 숫자를 지정해놓은 문자로 매핑 후 반환

숫자로 입력 받았더라도 고객이 보는 화면에서는 우리가 처음에 정한 문자열로 보여야했다. 이 방법에 대해 고민해보았는데, 따로 constant 파일을 만들어서 숫자와 문자를 매핑 시켜주기로했다.

 

실제 구현

(1) constants 파일(menu.type.js)

 

이걸 통해서 저장한 숫자 데이터를 문자와 매핑 시켜준다.

 

(2) menus.repository 파일

readAll = async (restaurantId) => {
    let menus = await prisma.menu.findMany({
      where: { restaurantId: +restaurantId },
      //메뉴타입 오름차순, 가격 오름차순 정렬
      orderBy: [{ menuType: "asc" }, { menuPrice: "asc" }],
    });

    menus = menus.map((menu) => {
      return {
        menuId: menu.menuId,
        menuName: menu.menuName,
        menuPrice: menu.menuPrice,
        menuType: menu.menuType,
        menuDescription: menu.menuDescription,
        menuImageUrl: menu.menuImageUrl,
      };
    });
    return menus;
  };

 

repository 파일에서는 정렬기능을 만져주었다. 기존 진행해왔던것처럼 orderBy를 사용했다.

사실 정렬 속에 정렬을 하는 것이 굉장히 복잡할것이라 생각했는데, 찾아보니 굉장히 간단하게 구현이 가능한 부분이었다.

 

(2) menus.service 파일

//메뉴 목록 조회
readAll = async (restaurantId) => {
    const menus = await this.menusRepository.readAll(restaurantId);

	//메뉴 타입 문자로 변환
    const formattedMenus = menus.map((menu) => this.formatMenuForOutput(menu));

    return formattedMenus;
  };

//메뉴 상세 조회
  readById = async (restaurantId, menuId) => {
    const menu = await this.menusRepository.readById(restaurantId, menuId);

    //존재하는 메뉴인지 확인
    if (!menu) {
      throw new HttpError.NotFound(MESSAGES.MENUS.COMMON.NOT_FOUND);
    }

    const formattedMenu = this.formatMenuForOutput(menu);

    return formattedMenu;
  };

  //메뉴 타입 변환 메서드
  formatMenuForOutput(menu) {
    return {
      ...menu,
      menuType: MENU_TYPES[menu.menuType],
    };
  }

 

비즈니스 로직을 수행하는 service 단계에서 숫자를 원하는 문자로 변환해주었다.

메뉴 목록 조회는 배열형식이기 때문에 map함수를 통해 변환 메서드를 호출해 문자열로 변환 후 반환해주었다.

메뉴 상세 조회는 객체 형식이기 때문에 변환 메서드를 바로 적용시켜 문자열로 변환 후 반환해주었다.

메뉴 타입 변환 메서드는 단순하게 다른 메뉴 목록은 그대로 반환하되, menuType 부분만 작성해둔 constant 파일을 통해 변환시켜주었다.

 

 

카테고리 별로 나누어 원하는 순서로 정렬해 보여주는 것이 굉장히 복잡할 것이라 생각했었는데, 생각보다 어렵지 않았다. 다 팀원들의 아이디어와 일단 찾아보고 시도해보는 자세로 하나를 또 구현해 낼 수 있었다. 팀원들에게 의견을 구하고 도전하는 자세의 중요성을 느꼈다. 앞으로 기능을 구성할 때 겁부터 먹지말고 우선은 시도해본다 생각하고 찾아보도록 해야겠다고 다짐하게 되었다.

반응형

댓글