개인 프로젝트 MenuMate

MenuMate 외부 API Raw타입 정규화 과정 정리, 레시피 페이지 조회 흐름 요약

dev_in 2026. 3. 30. 20:57

레시피 페이지 또한 외부 API의 Raw 타입을 그대로 쓰기 보다는 정규화 하여 프론트 차원에서 쓰기 좋은 함수로 만들 필요가 있었습니다. 이번 글을 그 과정 및 과정에서 고민한 사항들을 정리한 것입니다.

 

문제점

식약처의 조리식품 DB의 경우, 조리 단계를 배열이 아닌 string 타입이 펼쳐진 구조로 제시하고 있었습니다. 

// 조리 단계 Raw 데이터 타입 예시
export type RecipeDetailRaw = {
MANUAL01: string;
MANUAL02: string;
MANUAL03: string;
MANUAL04: string;
MANUAL05: string;
MANUAL06: string;
MANUAL07: string;
MANUAL08: string;
MANUAL09: string;
MANUAL10: string;
MANUAL11: string;
MANUAL12: string;
MANUAL13: string;
MANUAL14: string;
MANUAL15: string;
MANUAL16: string;
MANUAL17: string;
MANUAL18: string;
MANUAL19: string;
MANUAL20: string;
};

이런 식의 펼쳐진 데이터 구조를 그대로 쓰기 보다는 배열 형식으로 바꿔주는 것이 map()을 돌릴 수도 있어 관리가 편할 것이라 생각했습니다.

 

개선 방안

const extractRecipeSteps = (raw: RecipeDetailRaw): string[] => {
  const manualSteps = [
    raw.MANUAL01,
    raw.MANUAL02,
    raw.MANUAL03,
    raw.MANUAL04,
    raw.MANUAL05,
    raw.MANUAL06,
    raw.MANUAL07,
    raw.MANUAL08,
    raw.MANUAL09,
    raw.MANUAL10,
    raw.MANUAL11,
    raw.MANUAL12,
    raw.MANUAL13,
    raw.MANUAL14,
    raw.MANUAL15,
    raw.MANUAL16,
    raw.MANUAL17,
    raw.MANUAL18,
    raw.MANUAL19,
    raw.MANUAL20,
  ];

  return manualSteps.map((step) => step?.trim() ?? '').filter((step) => step.length > 0);
};

해당 함수를 추가함으로써 펼쳐진 필드 구조를 배열로 바꿨습니다. 뿐만 아니라 trim()으로 앞뒤 공백 제거를 하고 빈 문자열(비어있는 조리 과정)은 제거하도록 했습니다.

 

정규화 함수 추가

 

원래의 목적이었던 전체 Raw 데이터 타입을 내부 타입으로 바꾸는 정규화 함수 또한 추가했습니다.

export const normalizeRecipeDetail = (raw: RecipeDetailRaw): RecipeDetail => {
  return {
    id: raw.RCP_SEQ?.trim() ?? '',
    name: raw.RCP_NM?.trim() ?? '',
    imageUrl: raw.ATT_FILE_NO_MAIN?.trim() ?? '',
    ingredients: raw.RCP_PARTS_DTLS?.trim() ?? '',
    steps: extractRecipeSteps(raw),
  };
};

 

 

레시피 페이지의 사용자 조회 흐름 간단 정리

  1. 사용자가 검색 결과 카드를 클릭
  2. /recipes/[id] 진입
  3. page.tsx에서 id 확인
  4. 내부 API 호출
  5. /api/recipes/[id]
  6. 외부 공공 API 호출
  7. Raw 데이터 수신
  8. normalizeRecipeDetail()로  내부 타입 변환
  9. 페이지에 전달
  10. UI 렌더링