MIRROR 구축: Perfect Corp API를 활용한 럭셔리 AI 패션 가상 피팅 앱

발행: (2026년 3월 7일 PM 01:31 GMT+9)
6 분 소요
원문: Dev.to

Source: Dev.to

MIRROR이란?

MIRROR는 고급 제품 탐색 경험과 AI 기반 가상 착용을 결합한 풀스택 웹 앱입니다.

  • 사용자가 제품을 탐색합니다.
  • 착용 모달을 열고 사진을 업로드하면 AI가 생성한 미리보기를 통해 해당 아이템을 착용한 모습을 확인합니다.
  • 페이지를 떠나지 않고 바로 장바구니에 아이템을 추가합니다.

앱은 각각 고유한 Perfect Corp 엔드포인트와 페이로드 구조를 가진 네 가지 제품 카테고리를 지원합니다:

  • 의류
  • 신발
  • 가방
  • 귀걸이

MIRROR 홈 페이지 (Cottonbro Studio 사진)

기술 스택

레이어기술
프론트엔드React, React Router, Context API, custom CSS (UI 프레임워크 없음)
백엔드Node.js + Express
AIPerfect Corp S2S (Server‑to‑Server) API
사진 저장localStorage (최대 10개의 저장된 사용자 사진)
카트localStorage와 수량 집계

아키텍처

핵심 아키텍처 결정은 프론트엔드를 Perfect Corp와 완전히 분리하는 것이었습니다. React 앱은 Perfect Corp를 직접 호출하지 않으며, 모든 AI 요청은 Express 백엔드를 통해 전달됩니다.

Client (React) → POST /api/tryon → Express Server → Perfect Corp S2S API

Perfect Corp의 API는 사용자 사진과 제품 참조 이미지 모두에 대해 공개 접근 가능한 URL을 요구합니다. 따라서 서버는 다음과 같이 동작합니다:

  1. 업로드된 사용자 사진을 디스크에 저장합니다.
  2. 공개 URL을 생성합니다 (ngrok을 개발 환경에서 사용).

제품 유형별 동적 엔드포인트 라우팅

Perfect Corp는 제품 카테고리마다 다른 엔드포인트를 사용하며, 각각 고유한 페이로드 형태를 기대합니다. 저는 깔끔한 switch‑기반 설정 조회로 이를 해결했습니다:

function getPerfectConfig(productType) {
  switch (String(productType || "").toLowerCase()) {
    case "cloth":
      return {
        startUrl: "https://yce-api-01.makeupar.com/s2s/v2.0/task/cloth",
        /* …other config… */
      };
    case "earrings":
      return {
        startUrl:
          "https://yce-api-01.makeupar.com/s2s/v2.0/task/2d-vto/earring",
        /* …other config… */
      };
    case "shoes":
      return {
        startUrl: "https://yce-api-01.makeupar.com/s2s/v2.0/task/shoes",
        /* …other config… */
      };
    case "bag":
      return {
        startUrl: "https://yce-api-01.makeupar.com/s2s/v2.0/task/bag",
        /* …other config… */
      };
    default:
      throw new Error(`Unsupported product type: ${productType}`);
  }
}

buildPayload()는 각 유형에 맞는 요청 본문을 생성합니다:

  • 의류garment_categorychange_shoes가 필요합니다.
  • 신발 / 가방gender 필드가 필요합니다.
  • 귀걸이 – 가장 복잡함: ref_file_urls(배열), source_info, object_infos가 필요합니다.

MIRROR 아이템 페이지 (Cottonbro Studio 사진)

작업‑폴링 패턴

Perfect Corp의 API는 비동기식입니다:

  1. POST → 작업 시작 → task_id 수신.
  2. GET/task/{task_id} 를 폴링하여 task_status === "success" 가 될 때까지.

재사용 가능한 폴러를 만들었습니다:

async function pollPerfect({
  pollBaseUrl,
  token,
  taskId,
  intervalMs = 2000,
  maxAttempts = 120,
}) {
  const headers = { Authorization: `Bearer ${token}` };

  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    const res = await fetch(`${pollBaseUrl}/task/${taskId}`, { headers });
    const data = await res.json();

    if (data.task_status === "success") return data;
    if (data.task_status === "failed") throw new Error("Task failed");

    await new Promise((r) => setTimeout(r, intervalMs));
  }
  throw new Error("Polling timed out");
}

로컬 개발 설정

# public URL을 위한 환경 변수 설정 (ngrok)
echo "PUBLIC_BASE_URL=https://your-ngrok-url.ngrok.app" >> server/.env

# 서버 노출 (Perfect Corp는 public URL이 필요합니다)
ngrok http 5000

# 백엔드와 프론트엔드 시작
node server/index.js
cd client && npm start

마무리

MIRROR는 해커톤 형식으로 AI 기반 패션 기술을 탐구할 수 있는 좋은 방법이었습니다. 가장 흥미로운 엔지니어링 과제는 각 제품 카테고리마다 다른 API 계약을 조율하면서 프런트엔드 인터페이스를 깔끔하고 일관되게 유지하는 것이었습니다.

Perfect Corp의 가상 착용 API를 통합하려는 경우, 사전에 알아야 할 가장 큰 사항은 공개 URL 요구사항입니다. 시작하기 전에 이미지 호스팅 전략을 계획하면 디버깅에 많은 시간을 절약할 수 있습니다.

전체 소스는 GitHub에 있습니다 – 자유롭게 살펴보거나 자체 착용 프로젝트의 참고 자료로 사용하세요.

여기에서 저장소 보기

0 조회
Back to Blog

관련 글

더 보기 »