DEV Community

Cover image for API 모킹 사용 사례: API 모의 시점 및 이유
Rihpig
Rihpig

Posted on • Originally published at apidog.com

API 모킹 사용 사례: API 모의 시점 및 이유

대부분의 팀은 API를 목업(mock)할 수 있습니다. 더 중요한 질문은 “언제 목업해야 하는가”입니다. 적절한 시점의 목업은 병목을 제거하지만, 습관적으로 만든 목업은 실제 API와 어긋난 유지보수 대상이 됩니다.

오늘 Apidog를 사용해 보세요

이 글은 목업을 “어떻게 만드는지”보다 “언제 써야 하는지”에 집중합니다. 다음 상황에서 목업이 실제로 효과적입니다.

  • 백엔드가 아직 완성되지 않았을 때 프론트엔드 개발을 진행해야 하는 경우
  • 429, 500, 타임아웃 같은 오류 경로를 재현해야 하는 경우
  • 느리거나 유료이거나 불안정한 서드파티 API를 테스트에서 제외해야 하는 경우
  • 데모와 프로토타입을 안정적으로 보여줘야 하는 경우
  • CI 테스트를 빠르고 결정론적으로 유지해야 하는 경우

병렬 프론트엔드 및 백엔드 개발

가장 흔한 목업 사용 사례입니다. 프론트엔드 팀은 아직 구현되지 않은 백엔드 엔드포인트가 필요하고, 백엔드 팀은 API를 만드는 중입니다. 이때 목업이 없으면 프론트엔드는 기다리거나, 실제 API와 연결할 때 깨질 가능성이 높은 가정 기반 코드를 작성하게 됩니다.

실행 순서는 간단합니다.

  1. 프론트엔드와 백엔드가 먼저 API 계약에 합의합니다.
  2. 계약은 가능하면 OpenAPI 문서로 작성합니다.
  3. 해당 스펙에서 목업 서버를 생성합니다.
  4. 프론트엔드는 목업 서버를 기준으로 UI와 API 클라이언트를 구현합니다.
  5. 백엔드는 같은 계약을 기준으로 실제 엔드포인트를 구현합니다.
  6. 백엔드가 준비되면 프론트엔드의 base URL만 실제 서버로 바꿉니다.

예를 들어 프론트엔드에서는 환경 변수만 바꿀 수 있게 구성합니다.

const API_BASE_URL =
  process.env.NEXT_PUBLIC_API_BASE_URL ?? "https://mock.example.com";

export async function getOrders() {
  const res = await fetch(`${API_BASE_URL}/orders`);

  if (!res.ok) {
    throw new Error(`Failed to fetch orders: ${res.status}`);
  }

  return res.json();
}
Enter fullscreen mode Exit fullscreen mode

개발 중에는 목업 URL을 사용합니다.

NEXT_PUBLIC_API_BASE_URL=https://mock.example.com
Enter fullscreen mode Exit fullscreen mode

백엔드가 준비되면 실제 API URL로 교체합니다.

NEXT_PUBLIC_API_BASE_URL=https://api.example.com
Enter fullscreen mode Exit fullscreen mode

핵심은 “프론트엔드가 임의로 만든 목업”이 아니라 “양 팀이 승인한 계약에서 생성된 목업”을 사용하는 것입니다. 공유된 사양에서 파생된 목업은 양 팀의 기대값을 맞춰주며, 이는 API 계약 테스트의 원리와 같습니다.

이 방식의 장점은 팀 전체에 영향을 줍니다.

  • 프론트엔드는 백엔드 완료를 기다리지 않고 기능을 구현합니다.
  • 백엔드는 반쯤 구현된 엔드포인트에 대한 임시 요청을 덜 받습니다.
  • 디자이너와 PM은 더 빨리 클릭 가능한 빌드를 확인합니다.
  • 계약이 변경되면 스펙을 업데이트하고 목업을 다시 생성하면 됩니다.

목업을 직접 손으로 유지하지 말고, 가능한 한 사양에서 생성하십시오. 그래야 계약 변경에 따른 유지보수 비용을 줄일 수 있습니다.

필요할 때 트리거할 수 없는 오류 경로 테스트하기

실제 API는 대부분 정상 상황에서 200을 반환합니다. 문제는 클라이언트 코드가 정상 응답만 처리해서는 안 된다는 점입니다.

클라이언트는 다음 상황도 처리해야 합니다.

  • 429 Too Many Requests
  • 500 Internal Server Error
  • 503 Service Unavailable
  • 잘못된 JSON
  • 응답 지연
  • 타임아웃
  • 도메인 규칙에 맞지 않는 데이터

하지만 정상적으로 동작하는 실제 서버는 테스트할 때 이런 응답을 쉽게 만들어주지 않습니다. 목업은 이 문제를 해결합니다.

예를 들어 목업 서버에서 다음 응답을 의도적으로 구성할 수 있습니다.

테스트 실패 시나리오 목업 설정 검증할 내용
서버 오류 500 반환 클라이언트가 재시도 후 우아하게 기능 저하
속도 제한 Retry-After 포함된 429 반환 클라이언트가 올바른 간격으로 대기
느린 네트워크 응답을 5초 지연 클라이언트가 타임아웃을 깔끔하게 처리
잘못된 페이로드 손상된 JSON 반환 파서가 앱 전체를 충돌시키지 않고 실패

클라이언트 코드에서는 이런 경로를 명확히 구현해야 합니다.

async function requestWithRetry(url: string, retries = 2) {
  const res = await fetch(url);

  if (res.status === 429) {
    const retryAfter = Number(res.headers.get("Retry-After") ?? "1");
    await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
    return requestWithRetry(url, retries);
  }

  if (res.status >= 500 && retries > 0) {
    await new Promise((resolve) => setTimeout(resolve, 1000));
    return requestWithRetry(url, retries - 1);
  }

  if (!res.ok) {
    throw new Error(`Request failed: ${res.status}`);
  }

  return res.json();
}
Enter fullscreen mode Exit fullscreen mode

이 로직은 실제 서버가 항상 200만 반환한다면 검증하기 어렵습니다. 목업을 사용하면 각 실패 경로를 반복 가능하게 테스트할 수 있습니다.

한 번도 실행되지 않은 오류 처리는 사실상 존재하지 않는 오류 처리와 같습니다. 목업을 철저한 API 검증과 함께 사용하여 실패 경로를 가정하지 말고 검증하십시오.

또 하나 중요한 실패 유형은 “HTTP 레벨에서는 성공이지만 도메인 규칙에는 맞지 않는 응답”입니다.

예시는 다음과 같습니다.

{
  "id": "order_123",
  "status": "UNKNOWN_STATUS",
  "totalPrice": -1000
}
Enter fullscreen mode Exit fullscreen mode

HTTP 상태 코드는 200일 수 있지만, 클라이언트는 이런 데이터를 안전하게 처리해야 합니다.

목업으로 다음 케이스를 만들어 보십시오.

  • 음수 가격
  • 정의되지 않은 enum 값
  • 빈 필수 필드
  • 존재하지 않는 페이지네이션 커서
  • 배열 대신 객체가 오는 응답
  • 숫자 대신 문자열이 오는 응답

실제 서버가 올바르게 동작한다면 이런 데이터는 보내지 않겠지만, 클라이언트의 방어 로직은 이런 입력으로 검증해야 합니다.

서드파티 API를 대신하기

테스트에서 실제 결제 처리기, 지도 API, 배송 API를 호출하면 문제가 생깁니다.

  • 느립니다.
  • 호출당 비용이 발생할 수 있습니다.
  • 속도 제한에 걸릴 수 있습니다.
  • 샌드박스가 불안정할 수 있습니다.
  • 외부 장애가 내부 테스트 실패로 이어집니다.

이럴 때는 서드파티 API를 목업하십시오.

실행 방식은 두 가지입니다.

  1. 실제 응답을 한 번 기록하여 fixture로 사용합니다.
  2. 공개 스키마 또는 문서에서 목업 응답을 생성합니다.

예를 들어 결제 승인 응답을 테스트 fixture로 저장할 수 있습니다.

{
  "paymentId": "pay_123",
  "status": "approved",
  "amount": 49000,
  "currency": "KRW"
}
Enter fullscreen mode Exit fullscreen mode

테스트에서는 실제 결제 API 대신 목업 서버를 호출합니다.

const PAYMENT_API_BASE_URL =
  process.env.PAYMENT_API_BASE_URL ?? "https://payment-mock.example.com";

export async function approvePayment(orderId: string) {
  const res = await fetch(`${PAYMENT_API_BASE_URL}/payments`, {
    method: "POST",
    body: JSON.stringify({ orderId }),
    headers: {
      "Content-Type": "application/json",
    },
  });

  if (!res.ok) {
    throw new Error("Payment approval failed");
  }

  return res.json();
}
Enter fullscreen mode Exit fullscreen mode

CI에서는 목업 URL을 사용합니다.

PAYMENT_API_BASE_URL=https://payment-mock.example.com
Enter fullscreen mode Exit fullscreen mode

이렇게 하면 테스트는 빠르고, 무료이며, 결정론적으로 실행됩니다. 공급업체 샌드박스가 다운되어도 테스트는 계속 실행됩니다.

단, 유지보수 비용이 있습니다. 서드파티는 API를 변경할 수 있고, 목업은 이를 자동으로 알지 못합니다. 따라서 예약 작업을 하나 두는 것이 좋습니다.

  • 하루 또는 몇 시간마다 실제 서드파티 샌드박스를 호출합니다.
  • 응답 형태가 현재 목업 스키마와 일치하는지 확인합니다.
  • 불일치가 발생하면 팀에 알립니다.
  • 공급업체 변경 로그도 함께 모니터링합니다.

즉, 일반 테스트는 목업으로 빠르게 실행하고, 별도의 얇은 계약 확인만 실제 서드파티에 대해 실행하십시오.

데모 및 프로토타입 구동하기

클라이언트 앞에서 실제 서비스를 호출하는 데모는 위험합니다.

  • 쿼리가 느릴 수 있습니다.
  • 결과가 비어 있을 수 있습니다.
  • 데이터가 보기 좋지 않을 수 있습니다.
  • 외부 서비스가 장애를 일으킬 수 있습니다.
  • 네트워크가 불안정할 수 있습니다.

데모에서는 “실제성”보다 “제어 가능성”이 더 중요할 때가 많습니다. 목업을 사용하면 청중에게 보여줄 데이터를 정확하게 구성할 수 있습니다.

예를 들어 대시보드 데모라면 다음 데이터를 고정할 수 있습니다.

{
  "salesToday": 1280000,
  "ordersToday": 342,
  "deliveryRate": 98.7,
  "topProducts": [
    {
      "name": "API Pro Plan",
      "sales": 120
    },
    {
      "name": "API Team Plan",
      "sales": 84
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

검색 데모라면 항상 깔끔한 결과를 반환하도록 만들 수 있습니다.

{
  "query": "mock api",
  "total": 3,
  "items": [
    {
      "title": "Mock API 시작하기",
      "url": "/docs/mock-api"
    },
    {
      "title": "API 계약 테스트",
      "url": "/docs/contract-testing"
    },
    {
      "title": "CI에서 API 테스트 자동화",
      "url": "/docs/ci-api-testing"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

프로토타입에서도 목업은 유용합니다. 백엔드가 없더라도 UI 흐름을 먼저 검증할 수 있습니다.

작업 순서는 다음과 같습니다.

  1. 제품 플로우를 정의합니다.
  2. 각 화면에서 필요한 API 응답 형태를 작성합니다.
  3. 목업 서버가 해당 응답을 반환하도록 구성합니다.
  4. 프론트엔드는 실제 API처럼 목업을 호출합니다.
  5. 사용자 테스트 또는 내부 리뷰를 진행합니다.
  6. 계약이 확정되면 백엔드는 같은 형태로 실제 API를 구현합니다.

이 방식의 장점은 프로토타입 코드가 버려지는 코드가 아닐 수 있다는 점입니다. 목업이 최종 API와 동일한 응답 형태를 제공한다면, 프론트엔드 코드는 나중에 base URL만 바꿔 실제 제품 코드가 될 수 있습니다.

이 분야의 도구 비교는 온라인 API 목업 도구에 대한 글에서 다룹니다.

CI를 빠르고 안정적으로 유지하기

CI에서 외부 서비스를 직접 호출하는 테스트 스위트는 외부 서비스의 문제를 그대로 상속합니다.

예를 들어 다음 문제가 발생할 수 있습니다.

  • 일시적인 네트워크 오류
  • 속도 제한
  • 느린 응답
  • 공유 스테이징 데이터 충돌
  • 다른 빌드가 변경한 상태
  • 외부 샌드박스 장애

이런 실패는 검토 중인 코드와 관련이 없는데도 CI를 빨간색으로 만듭니다. 불안정한 테스트가 반복되면 개발자는 실패를 무시하기 시작합니다. 그러면 CI의 가치가 사라집니다.

CI에서는 외부 종속성을 목업하여 테스트를 고립시키는 것이 좋습니다.

권장 구조는 다음과 같습니다.

Pull Request / Commit마다 실행
├─ 단위 테스트
├─ 컴포넌트 테스트
├─ 목업 API 기반 API 클라이언트 테스트
└─ 목업 서드파티 기반 서비스 테스트

스케줄 기반으로 실행
├─ 실제 내부 API 계약 테스트
├─ 실제 서드파티 샌드박스 계약 확인
└─ 목업과 실제 응답 형태 비교
Enter fullscreen mode Exit fullscreen mode

커밋마다 실행되는 테스트는 빠르고 결정론적이어야 합니다. 실제 외부 API와의 확인은 별도 스케줄에서 얇게 실행합니다. 이러한 분리는 건전한 CI/CD 테스트 파이프라인의 핵심입니다.

예를 들어 GitHub Actions에서는 환경별 base URL을 나눌 수 있습니다.

name: test

on:
  pull_request:
  push:

jobs:
  test:
    runs-on: ubuntu-latest

    env:
      API_BASE_URL: https://mock-api.example.com
      PAYMENT_API_BASE_URL: https://payment-mock.example.com

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npm test
Enter fullscreen mode Exit fullscreen mode

실제 API 계약 확인은 스케줄로 분리합니다.

name: contract-check

on:
  schedule:
    - cron: "0 */6 * * *"

jobs:
  contract-check:
    runs-on: ubuntu-latest

    env:
      API_BASE_URL: https://api.example.com

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npm run test:contract
Enter fullscreen mode Exit fullscreen mode

이렇게 하면 PR 테스트는 빠르게 유지하면서도, 목업이 실제 API와 멀어지는 문제를 감지할 수 있습니다.

속도 향상은 단순한 편의가 아닙니다. 12분 걸리던 테스트가 90초로 줄어들면 팀의 작업 방식이 바뀝니다.

  • 개발자는 푸시 전에 테스트를 실제로 실행합니다.
  • 리뷰어는 diff를 읽는 동안 결과를 확인합니다.
  • 실패가 발생하면 외부 문제가 아니라 코드 문제일 가능성이 높습니다.
  • 팀은 CI 결과를 신뢰합니다.

자동화 테스트의 가치는 신뢰에서 나옵니다. 빠르고 고립된 테스트 스위트는 그 신뢰를 만들기 쉽습니다.

목업을 사용하지 말아야 할 때

목업에는 명확한 실패 모드가 있습니다. 실제 API와 더 이상 일치하지 않는데도 테스트가 계속 통과하는 상황입니다. 이 경우 테스트는 현실이 아니라 가상의 시스템을 검증하고 있는 것입니다.

다음 경우에는 목업을 사용하지 마십시오.

1. 통합 자체를 검증하는 테스트

통합 테스트와 end-to-end 테스트는 실제 경계를 검증하기 위해 존재합니다. 이 테스트에서 경계를 목업하면 테스트 목적이 사라집니다.

예를 들어 다음은 실제 API를 호출해야 합니다.

  • 프론트엔드와 백엔드가 실제로 연결되는지 확인
  • 인증 토큰이 실제 서버에서 유효한지 확인
  • 실제 결제 샌드박스와 통신 가능한지 확인
  • 배포된 서비스 간 네트워크 경로가 정상인지 확인

2. 실제 서비스와 한 번도 대조하지 않는 종속성

목업은 시간이 지나면 오래될 수 있습니다. 따라서 실제 서비스와 비교하는 계약 확인이 없다면 위험합니다.

목업을 쓰려면 최소한 다음 중 하나를 유지하십시오.

  • OpenAPI 스키마 기반 검증
  • 실제 API에 대한 예약된 계약 테스트
  • 서드파티 샌드박스 응답 비교
  • 변경 로그 모니터링

3. 실제 서비스가 충분히 빠르고 안정적인 경우

테스트 환경의 실제 서비스가 빠르고, 무료이며, 신뢰할 수 있다면 목업은 오히려 오버헤드입니다.

목업은 다음 목적이 있을 때 사용하십시오.

  • 속도
  • 격리
  • 제어
  • 비용 절감
  • 실패 시나리오 재현

그 목적이 없다면 목업을 추가하지 않는 편이 낫습니다.

일반적인 규칙은 다음과 같습니다.

커밋마다 실행되는 테스트는 목업으로 빠르게 유지하고, 실제 API와의 계약 확인은 작고 정직한 별도 테스트로 유지하십시오.

목업과 계약 확인을 한 곳에서 관리하고 싶다면 Apidog는 API 디자인에서 목업을 생성하고, 목업과 실제 엔드포인트 모두에 대해 테스트를 실행할 수 있습니다. 설정하려면 Apidog를 다운로드하고 기존 사양에서 시작하십시오. 개념적 기초가 필요하다면 목업 API가 실제로 무엇인지 먼저 확인하십시오.

자주 묻는 질문

실제 API를 호출하는 대신 언제 API를 목업해야 합니까?

속도, 격리 또는 제어가 필요할 때 목업하십시오. 대표적인 경우는 다음과 같습니다.

  • 미완성 백엔드를 기다리지 않고 프론트엔드 개발을 진행할 때
  • 실제 서버가 만들기 어려운 오류 응답을 테스트할 때
  • 느리거나 유료인 서드파티 API를 테스트에서 제외할 때
  • 데모 데이터를 안정적으로 보여줘야 할 때
  • CI를 빠르고 결정론적으로 유지해야 할 때

계약 테스트와 end-to-end 테스트에서는 실제 API를 호출하십시오.

목업은 통합 테스트를 대체합니까?

아닙니다. 목업은 단위 테스트, 컴포넌트 테스트, API 클라이언트 테스트를 빠르게 만드는 데 적합합니다.

통합 테스트와 계약 테스트는 실제 경계를 검증해야 합니다. 이 테스트를 목업하면 실제 서비스가 계약을 지키는지 확인할 수 없습니다.

목업이 오래되지 않도록 하려면 어떻게 해야 합니까?

가능하면 공유 스키마, 특히 OpenAPI에서 목업을 생성하십시오. 계약이 변경되면 스키마를 업데이트하고 목업을 다시 생성합니다.

또한 실제 API에 대해 예약된 계약 테스트를 실행하십시오. 이 테스트는 실제 응답이 여전히 스키마와 일치하는지 확인합니다. 이렇게 하면 변경 사항이 사용자에게 도달하기 전에 감지됩니다.

제가 제어할 수 없는 서드파티 API를 목업할 수 있습니까?

네. 오히려 강력한 사용 사례입니다.

서드파티의 실제 응답을 기록하거나 공개된 스키마에서 목업을 만들고, 일반 테스트는 목업을 대상으로 실행하십시오. 단, 공급업체가 API를 변경할 수 있으므로 실제 샌드박스에 대한 예약된 확인을 추가해야 합니다.

목업은 데모 및 프로토타입에 유용합니까?

매우 유용합니다. 목업을 사용하면 청중에게 보여줄 데이터를 정확하게 스크립트할 수 있습니다. 실시간 장애, 느린 쿼리, 빈 데이터, 불안정한 네트워크 때문에 데모가 망가지는 위험을 줄일 수 있습니다.

프로토타입에서는 백엔드가 없어도 UI 흐름을 먼저 구축하고 검증할 수 있습니다. 최종 API 계약과 동일한 형태로 목업을 구성하면, 프로토타입 코드를 실제 제품 코드로 이어갈 수도 있습니다.

Top comments (0)