Mockoon

Mockoon은 개발자가 빠르고 쉽게 API를 모킹(가짜로 구현)할 수 있는 오픈 소스 데스크톱 애플리케이션이다.
이 도구는 2017년에 처음 출시되었으며, API 개발 및 테스트 과정을 간소화하기 위해 설계되었다.

Mockoon의 주요 특징:

Mockoon이 해결하는 개발 문제

백엔드 개발자로서 다음과 같은 상황에서 Mockoon이 매우 유용하다:

  1. 백엔드 API가 아직 개발 중일 때: 프론트엔드 팀이 백엔드 API 완성을 기다리지 않고 개발을 진행할 수 있다.
  2. 테스트 환경 구축: 실제 서버에 의존하지 않고 다양한 응답과 시나리오를 테스트할 수 있다.
  3. 외부 API 의존성 제거: 개발 과정에서 외부 API 호출 횟수를 줄이거나 비용을 절감할 수 있다.
  4. 오프라인 개발: 인터넷 연결 없이도 API 응답을 시뮬레이션할 수 있다.
  5. 프로토타이핑: 실제 구현 전에 API 설계를 빠르게 테스트할 수 있다.

Mockoon 설치 및 기본 설정

Mockoon은 설치가 매우 간단하다:

  1. Mockoon 공식 웹사이트에서 운영 체제에 맞는 버전 다운로드
  2. 설치 파일 실행 및 설치 완료
  3. 애플리케이션 실행

기본 설정:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// Mockoon은 JSON 형식으로 설정을 저장합니다.
// 설정 예시:
{
  "uuid": "1095c7e0-e2fc-11ea-8e7a-1f0c56a5665e",
  "name": "My API",
  "endpointPrefix": "",
  "latency": 0,
  "port": 3000,
  "routes": []
}

Mockoon의 주요 기능

기본 라우트 설정

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// GET /users 라우트 설정 예시
{
  "uuid": "2d3c7a90-e2fc-11ea-8e7a-1f0c56a5665e",
  "documentation": "사용자 목록 반환",
  "method": "get",
  "endpoint": "users",
  "responses": [
    {
      "uuid": "3a7c8b10-e2fc-11ea-8e7a-1f0c56a5665e",
      "body": "{\n  \"users\": [\n    {\n      \"id\": 1,\n      \"name\": \"김철수\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"이영희\"\n    }\n  ]\n}",
      "latency": 0,
      "statusCode": 200,
      "label": "성공 응답",
      "headers": [
        {
          "key": "Content-Type",
          "value": "application/json"
        }
      ],
      "filePath": "",
      "sendFileAsBody": false,
      "rules": [],
      "rulesOperator": "OR",
      "disableTemplating": false,
      "fallbackTo404": false
    }
  ],
  "enabled": true
}

GUI에서는 이러한 설정을 직관적으로 작성할 수 있다.

동적 응답 생성

Mockoon은 템플릿 엔진을 사용하여 동적 응답을 생성할 수 있다:

1
2
3
4
// 템플릿 문법 예시 (Handlebars 기반)
{
  "body": "{\n  \"timestamp\": \"{{now}}\",\n  \"randomId\": \"{{faker 'datatype.uuid'}}\",\n  \"userName\": \"{{faker 'name.firstName'}} {{faker 'name.lastName'}}\"\n}"
}

이렇게 하면 매 요청마다 다른 응답을 생성할 수 있다.

조건부 응답

특정 조건에 따라 다른 응답을 반환할 수 있다:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// 쿼리 파라미터에 따른 조건부 응답
{
  "rules": [
    {
      "target": "query",
      "modifier": "type",
      "value": "premium",
      "operator": "equals"
    }
  ],
  "body": "{\n  \"message\": \"프리미엄 콘텐츠입니다.\"\n}"
}

요청 로깅

모든 수신 요청은 로그에 기록되어 디버깅에 유용하게 활용할 수 있다.

OpenAPI 가져오기/내보내기

OpenAPI(Swagger) 명세를 가져와서 자동으로 모킹 서버를 생성하거나 Mockoon 설정을 OpenAPI 형식으로 내보낼 수 있다.

파일 서빙

정적 파일을 서빙할 수 있어 이미지나 문서 등의 파일 다운로드 시뮬레이션이 가능하다.

실제 개발 워크플로우에 Mockoon 통합하기

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

1
2
3
4
5
6
// 프로젝트 계획 단계
1. API 인터페이스 정의 (엔드포인트, 요청/응답 형식)
2. Mockoon으로 모든 API 엔드포인트 모킹
3. 프론트엔드 팀은 모킹된 API를 사용하여 개발 시작
4. 백엔드 팀은 실제 API 구현 진행
5. 완성된 백엔드 API로 전환

테스트 자동화와 통합

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# Python 테스트 코드 예시
def setup_module(module):
    # Mockoon CLI 시작
    subprocess.Popen(["mockoon-cli", "start", "--data", "mockoon.json"])
    time.sleep(1)  # 서버 시작 대기

def teardown_module(module):
    # Mockoon CLI 종료
    subprocess.Popen(["mockoon-cli", "stop"])

def test_api_client():
    # 테스트용 API 클라이언트 - 모킹된 서버로 요청
    client = APIClient(base_url="http://localhost:3000")
    response = client.get_users()
    assert response.status_code == 200
    assert len(response.json()["users"]) > 0

CI/CD 환경에서 Mockoon 활용

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# GitHub Actions 워크플로우 예시
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      
      - name: Setup Mockoon CLI
        run: npm install -g @mockoon/cli
      
      - name: Start Mockoon server
        run: mockoon-cli start --data ./mockoon.json
      
      - name: Run tests
        run: npm test
      
      - name: Stop Mockoon server
        run: mockoon-cli stop

Mockoon 고급 사용법

7.1 환경 변수 활용

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// 환경 변수 정의
{
  "variables": [
    {
      "key": "apiVersion",
      "value": "v1"
    },
    {
      "key": "baseUrl",
      "value": "api.example.com"
    }
  ]
}

// 응답에서 환경 변수 사용
{
  "body": "{\n  \"apiUrl\": \"https://{{baseUrl}}/{{apiVersion}}\"\n}"
}

Faker.js를 활용한 대량 데이터 생성

1
2
3
4
// 랜덤 사용자 데이터 생성 예시
{
  "body": "{\n  \"users\": [\n    {{#repeat 10}}\n    {\n      \"id\": {{@index}},\n      \"name\": \"{{faker 'name.firstName'}} {{faker 'name.lastName'}}\",\n      \"email\": \"{{faker 'internet.email'}}\",\n      \"phone\": \"{{faker 'phone.phoneNumber'}}\"\n    }{{#unless @last}},{{/unless}}\n    {{/repeat}}\n  ]\n}"
}

이 코드는 10명의 랜덤 사용자 데이터를 생성한다.

CRUD 작업 시뮬레이션

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// POST 요청 처리 및 응답
{
  "method": "post",
  "endpoint": "users",
  "responses": [
    {
      "statusCode": 201,
      "body": "{\n  \"message\": \"사용자가 생성되었습니다.\",\n  \"user\": {{body}}\n}"
    }
  ]
}

이렇게 하면 클라이언트가 보낸 요청 본문(body)을 응답에 포함시킬 수 있다.

Mockoon CLI 활용

터미널에서:

1
2
3
4
5
6
7
8
# Mockoon CLI 설치
npm install -g @mockoon/cli

# 설정 파일로 서버 시작
mockoon-cli start --data mockoon.json --port 3000

# API 호출 테스트
curl http://localhost:3000/users

실제 프로젝트 적용 사례 연구

마이크로서비스 아키텍처에서의 활용

마이크로서비스 환경에서 각 서비스를 독립적으로 개발하고 테스트할 때 Mockoon을 활용할 수 있다:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 사용자 서비스 모킹
{
  "port": 3001,
  "routes": [
    {
      "method": "get",
      "endpoint": "users/:id",
      "responses": [...]
    }
  ]
}

// 주문 서비스 모킹
{
  "port": 3002,
  "routes": [
    {
      "method": "get",
      "endpoint": "orders/:id",
      "responses": [...]
    }
  ]
}

각 서비스를 별도의 포트에서 실행하여 전체 시스템을 시뮬레이션할 수 있다.

모바일 앱 개발 적용 사례

모바일 앱 개발자는 백엔드 API가 아직 준비되지 않았을 때 Mockoon을 사용하여 개발을 진행할 수 있다:

1
2
3
4
5
6
7
8
// iOS에서 모킹된 API 호출 예시
let url = URL(string: "http://localhost:3000/api/users")!
URLSession.shared.dataTask(with: url) { (data, response, error) in
    if let data = data {
        let users = try? JSONDecoder().decode([User].self, from: data)
        // UI 업데이트
    }
}.resume()

Mockoon 베스트 프랙티스

프로젝트 구조화

1
2
3
4
5
6
7
project/
├── mockoon/
│   ├── dev.json        # 개발 환경 설정
│   ├── test.json       # 테스트 환경 설정
│   └── demo.json       # 데모 환경 설정
├── src/
└── tests/

버전 관리 및 팀 협업

1
2
3
4
5
6
# .gitignore 파일 예시
mockoon/local.json  # 로컬 개발용 설정은 제외
mockoon/tmp.json    # 임시 설정 파일 제외

# 공유해야 할 설정 파일은 버전 관리에 포함
mockoon/shared.json

문서화 및 주석 활용

Mockoon의 문서화 필드를 적극 활용하여 각 엔드포인트의 목적과 사용법을 기록한다:

1
2
3
{
  "documentation": "## 사용자 API\n\n이 엔드포인트는 사용자 정보를 제공합니다.\n\n### 쿼리 파라미터\n- `type`: 사용자 유형 (일반/프리미엄)\n- `limit`: 최대 반환 개수"
}

Mockoon의 한계와 대안

한계점

  1. 상태 관리 제한: 복잡한 상태 변화를 시뮬레이션하기 어려움
  2. 복잡한 로직 구현: 고급 비즈니스 로직 구현에 제한적
  3. 실시간 통신: WebSocket 등의 실시간 프로토콜 지원 제한적
  4. 대규모 팀 협업: 여러 개발자가 동시에 같은 모킹 설정을 수정하기 어려움

대체 및 보완 도구

  1. Wiremock: 더 복잡한 모킹 시나리오 지원
  2. JSON Server: RESTful API를 위한 간단한 모킹
  3. Mirage JS: 프론트엔드 중심의 API 모킹
  4. Nock: Node.js에서 HTTP 요청 모킹
  5. Prism: OpenAPI 기반 모킹 도구

실제 개발 과정에서의 Mockoon 활용 예시

다음은 실제 개발 과정에서 단계별로 Mockoon을 활용하는 방법:

API 설계 및 프로토타이핑

1
2
3
4
5
6
7
8
// 1. 기본 API 구조 설계
GET /api/products - 제품 목록
GET /api/products/:id - 제품 상세
POST /api/products - 제품 생성
PUT /api/products/:id - 제품 수정
DELETE /api/products/:id - 제품 삭제

// 2. Mockoon에서 각 엔드포인트 구현

프론트엔드 개발 지원

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// React 애플리케이션에서 모킹된 API 사용
import React, { useEffect, useState } from 'react';
import axios from 'axios';

function ProductList() {
  const [products, setProducts] = useState([]);
  
  useEffect(() => {
    // Mockoon에서 실행 중인 API 호출
    axios.get('http://localhost:3000/api/products')
      .then(response => {
        setProducts(response.data.products);
      })
      .catch(error => {
        console.error('API 호출 오류:', error);
      });
  }, []);
  
  return (
    <div>
      <h1>제품 목록</h1>
      <ul>
        {products.map(product => (
          <li key={product.id}>{product.name} - {product.price}</li>
        ))}
      </ul>
    </div>
  );
}

테스트 시나리오 구현

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// 다양한 응답 상태 시뮬레이션
{
  "uuid": "route-1",
  "method": "get",
  "endpoint": "api/products",
  "responses": [
    {
      "uuid": "response-success",
      "statusCode": 200,
      "label": "성공 응답",
      "body": "{\n  \"products\": [...]\n}"
    },
    {
      "uuid": "response-empty",
      "statusCode": 200,
      "label": "빈 목록",
      "body": "{\n  \"products\": []\n}",
      "rules": [
        {
          "target": "query",
          "modifier": "category",
          "value": "nonexistent",
          "operator": "equals"
        }
      ]
    },
    {
      "uuid": "response-error",
      "statusCode": 500,
      "label": "서버 오류",
      "body": "{\n  \"error\": \"서버 내부 오류가 발생했습니다.\"\n}",
      "rules": [
        {
          "target": "query",
          "modifier": "simulate",
          "value": "error",
          "operator": "equals"
        }
      ]
    }
  ]
}

용어 정리

용어설명