DEV Community

Cover image for API 명세 코드로 다루기: 의미와 방법
Rihpig
Rihpig

Posted on • Originally published at apidog.com

API 명세 코드로 다루기: 의미와 방법

API 계약은 위키 다이어그램, 지난 분기에 내보낸 Postman 컬렉션, 오래된 Markdown 문서에 동시에 흩어져 있을 때가 많습니다. 이 세 가지가 서로 다르면 팀은 추측으로 통합을 진행하게 되고, 추측은 API 연동을 깨뜨립니다.

오늘 Apidog를 사용해 보세요

해결책은 API 스펙을 코드처럼 다루는 것입니다. 하나의 OpenAPI 파일을 작성하고, Git에 커밋하고, 코드와 동일하게 리뷰합니다. 그런 다음 이 파일에서 모의 API, 테스트, 문서, SDK를 생성합니다. 스펙은 사후 문서가 아니라 팀 전체가 기준으로 삼는 계약이 됩니다.

이 글에서는 스펙-애즈-코드(spec-as-code)의 의미, OpenAPI 파일을 코드처럼 관리해야 하는 이유, 그리고 실제 워크플로에 적용하는 방법을 설명합니다.

스펙-애즈-코드(Spec-as-code)란 무엇인가

스펙-애즈-코드는 API 정의를 버전 관리되는 일반 텍스트 파일로 관리하는 방식입니다. 데이터베이스 레코드나 공유 링크가 있는 문서가 아니라, git diff, 브랜치, 병합, 리뷰가 가능한 파일입니다.

스펙-애즈-코드 개념

이 방식은 docs-as-code에서 출발합니다. 문서를 코드와 같은 저장소에 두고 같은 파이프라인으로 배포하듯, 스펙-애즈-코드는 API 계약 자체를 Git 워크플로 안에 넣습니다.

일반적으로 이 파일은 OpenAPI YAML 또는 JSON입니다. 이 파일이 기준이 되고, 다음 산출물이 여기서 생성됩니다.

  • 모의 API
  • 계약 테스트
  • API 문서
  • SDK 또는 클라이언트 코드

즉, 개발자가 /users/{id} 응답 구조를 확인할 때 오래된 위키를 찾지 않고 OpenAPI 파일을 확인합니다. QA는 같은 스펙을 기준으로 테스트를 작성하고, 파트너는 같은 스펙에서 생성된 SDK를 사용합니다.

스펙을 코드처럼 다뤄야 하는 이유

스펙이 Git에 파일로 존재하면 소스 코드에서 사용하는 워크플로를 그대로 적용할 수 있습니다.

1. Pull Request에서 변경 사항을 리뷰할 수 있다

엔드포인트 변경은 PR의 diff로 드러납니다.

예를 들어 다음 변경은 리뷰어가 즉시 확인할 수 있습니다.

 status:
   type: string
-  enum: [pending, shipped, delivered]
+  enum: [pending, shipped, delivered, canceled]
Enter fullscreen mode Exit fullscreen mode

필드 추가, 상태 코드 변경, 응답 스키마 변경이 모두 리뷰 대상이 됩니다. 호환성을 깨는 변경은 프로덕션에서 발견되는 문제가 아니라 병합 전에 논의되는 변경 사항이 됩니다.

이것이 Git-네이티브 API 워크플로의 핵심입니다.

2. YAML diff는 읽기 쉽다

일반 YAML은 Git diff와 잘 맞습니다. 몇 줄만 바뀌어도 무엇이 변경되었는지 바로 확인할 수 있습니다.

반대로 내보낸 바이너리 파일이나 호스팅 도구 내부의 변경 기록만으로는 다음 질문에 답하기 어렵습니다.

  • 어떤 필드가 추가되었는가?
  • 어떤 응답 코드가 제거되었는가?
  • 어떤 변경이 breaking change인가?
  • 누가 언제 변경했는가?

스펙이 Git에 있으면 git diff, git blame, 커밋 기록이 그대로 작동합니다.

3. 버전 관리가 명확해진다

모든 변경에는 커밋, 작성자, 타임스탬프가 남습니다.

실무에서는 다음 작업이 가능해집니다.

# 릴리스 태그 생성
git tag api-v1.2.0

# v2 설계를 위한 브랜치 생성
git checkout -b api-v2

# 잘못된 스펙 변경 롤백
git revert <commit-sha>
Enter fullscreen mode Exit fullscreen mode

API 변경 기록이 감사 가능해지고, 릴리스별 계약도 추적할 수 있습니다. 태그와 브랜치 전략은 Git을 이용한 OpenAPI 버전 관리를 참고하세요.

4. 단일 진실 공급원을 만들 수 있다

모의 API, 테스트, 문서, SDK가 모두 같은 OpenAPI 파일에서 생성되면 서로 독립적으로 어긋나기 어렵습니다.

스펙을 수정합니다.

산출물을 다시 생성합니다.

모든 결과물이 같은 계약을 따릅니다.

고려 사항 호스팅된 도구의 스펙 코드로 관리하는 API 스펙
변경 검토 수동, 누락 가능 PR diff, 리뷰 가능
기록 제한적이거나 벤더 종속 전체 Git 로그
롤백 대부분 수동 git revert
진실 공급원 모호함 커밋된 파일
CI 통합 별도 연결 필요 네이티브 통합 가능

아티팩트로서의 OpenAPI

OpenAPI는 널리 지원되고 기계가 읽을 수 있기 때문에 스펙-애즈-코드에 적합합니다.

다음은 저장소에 둘 수 있는 OpenAPI 3.1 예시입니다.

openapi: 3.1.0
info:
  title: Orders API
  version: 1.2.0

paths:
  /orders/{orderId}:
    get:
      summary: Get an order by ID
      operationId: getOrder
      parameters:
        - name: orderId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: The requested order
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Order"
        "404":
          description: Order not found

components:
  schemas:
    Order:
      type: object
      required:
        - id
        - status
        - total
      properties:
        id:
          type: string
          format: uuid
        status:
          type: string
          enum:
            - pending
            - shipped
            - delivered
        total:
          type: number
          format: float
Enter fullscreen mode Exit fullscreen mode

이 파일이 API 계약입니다.

예를 들어 Ordercurrency 필드를 추가하면 diff는 명확합니다.

 required:
   - id
   - status
   - total
+  - currency

 properties:
   total:
     type: number
     format: float
+  currency:
+    type: string
+    example: KRW
Enter fullscreen mode Exit fullscreen mode

권장 구조는 다음처럼 서비스 코드 옆에 스펙을 두는 것입니다.

my-service/
├── src/
├── tests/
└── api/
    └── openapi.yaml
Enter fullscreen mode Exit fullscreen mode

이렇게 하면 구현과 계약이 같은 저장소에서 함께 이동합니다.

스펙에서 생성할 수 있는 것들

스펙-애즈-코드의 가치는 파일 자체보다 그 파일에서 생성되는 산출물에 있습니다.

모의 API

OpenAPI 스펙을 모의 서버에 연결하면 백엔드 구현 전에도 실행 가능한 API를 만들 수 있습니다.

프론트엔드와 모바일 팀은 다음과 같은 흐름으로 작업할 수 있습니다.

  1. OpenAPI에 엔드포인트 정의
  2. 모의 서버 생성
  3. 프론트엔드에서 모의 API 호출
  4. 백엔드 구현 완료 후 실제 API로 전환

스펙이 변경되면 모의 API도 같은 계약을 따릅니다.

계약 테스트

계약 테스트는 실행 중인 API가 OpenAPI 스펙과 일치하는지 검증합니다.

예를 들어 스펙에는 다음 응답이 정의되어 있다고 가정합니다.

responses:
  "200":
    description: User response
    content:
      application/json:
        schema:
          type: object
          required:
            - id
            - email
          properties:
            id:
              type: string
            email:
              type: string
Enter fullscreen mode Exit fullscreen mode

실제 API가 email을 누락하거나, 스펙에 없는 필드를 반환하거나, 잘못된 타입을 반환하면 테스트가 실패해야 합니다.

이 검사를 CI에 넣으면 고객이 문제를 발견하기 전에 빌드 단계에서 계약 불일치를 잡을 수 있습니다.

문서

OpenAPI 파일을 렌더링하면 API 참조 문서를 자동으로 만들 수 있습니다.

수동으로 엔드포인트 표를 작성할 필요가 없습니다. 문서는 스펙을 렌더링한 결과이므로, 스펙이 최신이면 문서도 최신입니다.

SDK

같은 OpenAPI 파일에서 여러 언어의 클라이언트 라이브러리를 생성할 수 있습니다.

예를 들어 파트너에게 다음과 같은 산출물을 제공할 수 있습니다.

  • TypeScript SDK
  • Python SDK
  • Java SDK
  • Go client

스펙이 현재 계약을 나타내면, 생성된 SDK도 현재 계약을 반영합니다.

OpenAPI에서 생성되는 산출물

Apidog가 스펙을 진실 공급원으로 만드는 방법

스펙-애즈-코드를 직접 구성하려면 여러 도구를 연결해야 합니다.

  • OpenAPI 편집기
  • 모의 서버
  • 문서 생성기
  • 계약 테스트 도구
  • Git 동기화
  • CI 검사

Apidog는 이 흐름을 하나의 워크플로로 묶습니다.

Apidog의 Spec-First 모드는 OpenAPI 파일을 신뢰할 수 있는 정의로 취급합니다. 엔드포인트를 스펙 기준으로 설계하면 Apidog는 모의 API, 테스트, 문서를 스펙과 동기화합니다.

Apidog Spec-First 워크플로

실무에서 중요한 기능은 양방향 Git 동기화입니다.

Apidog는 저장소의 OpenAPI 파일을 읽고, 변경 사항을 다시 저장소에 쓸 수 있습니다. 따라서 다음 두 작업 방식이 모두 가능합니다.

  • YAML을 직접 편집하고 Git에 커밋
  • Apidog의 시각적 편집기에서 수정 후 Git에 동기화

두 방식 모두 같은 OpenAPI 파일로 이어집니다. 팀은 PR 리뷰 흐름을 유지하면서 더 편한 편집 방식을 선택할 수 있습니다.

스펙 변경 사항을 GitHub로 푸시하는 방법은 GitHub에 OpenAPI 스펙을 동기화하는 방법을 참고하세요.

결과적으로 OpenAPI 파일은 단일 진실 공급원으로 유지되고, 시각적 도구는 그 파일을 대체하지 않고 그 위에서 동작합니다.

흔히 겪는 문제와 해결 방법

스펙-애즈-코드는 단순하지만, 도입 초기에 자주 발생하는 문제가 있습니다.

문제 1. 스펙과 구현이 어긋난다

스펙을 작성하는 것만으로는 충분하지 않습니다. 실행 중인 서비스가 스펙과 일치하는지 검증해야 합니다.

해결 방법은 CI에 계약 테스트를 추가하는 것입니다.

PR 생성
→ OpenAPI lint
→ 계약 테스트 실행
→ 스펙과 구현 불일치 시 빌드 실패
Enter fullscreen mode Exit fullscreen mode

불일치를 고객이 발견하게 두지 말고, 빌드가 먼저 실패하게 만드세요.

문제 2. 생성된 스펙과 수동 작성 스펙이 섞인다

스펙을 코드 주석에서 생성할지, OpenAPI 파일을 직접 작성할지 먼저 결정해야 합니다.

둘을 섞으면 어떤 파일이 권한 있는 소스인지 모호해집니다.

권장 원칙은 하나입니다.

  • 스펙이 진실 공급원이라면 코드 주석은 보조 정보로 둡니다.
  • 코드에서 스펙을 생성한다면 생성된 OpenAPI를 기준으로 리뷰합니다.
  • 두 방식을 동시에 마스터 소스로 두지 않습니다.

문제 3. 스펙을 계약이 아니라 문서로만 사용한다

읽기만 하는 스펙은 문서입니다.

모의 API, 테스트, SDK를 생성하는 스펙이 계약입니다.

스펙-애즈-코드의 가치를 얻으려면 최소 하나 이상의 산출물을 연결해야 합니다.

시작점으로는 다음 순서를 추천합니다.

  1. 문서 생성
  2. 모의 API 생성
  3. 계약 테스트 추가
  4. SDK 생성

문제 4. 리뷰 없이 병합한다

Git에 있는 스펙이라도 리뷰 없이 병합하면 효과가 제한적입니다.

스펙 변경도 코드 변경처럼 리뷰해야 합니다.

예를 들어 다음 항목을 PR 체크리스트에 넣을 수 있습니다.

## API 스펙 변경 체크리스트

- [ ] 응답 스키마 변경이 하위 호환성을 깨지 않는가?
- [ ] 새로운 필드가 required로 추가되었는가?
- [ ] 상태 코드 변경이 클라이언트에 영향을 주는가?
- [ ] 문서와 모의 API가 재생성되었는가?
- [ ] 계약 테스트가 통과하는가?
Enter fullscreen mode Exit fullscreen mode

시작하는 방법

스펙-애즈-코드는 한 번에 전체 시스템을 바꾸지 않아도 됩니다. 다음 순서로 점진적으로 도입할 수 있습니다.

1. OpenAPI 파일을 저장소에 커밋한다

먼저 스펙을 알려진 경로에 둡니다.

api/openapi.yaml
Enter fullscreen mode Exit fullscreen mode

이 파일이 API 계약의 기준이 됩니다.

2. PR 리뷰를 의무화한다

스펙 변경이 코드와 같은 리뷰 절차를 거치도록 설정합니다.

검토자는 diff를 기준으로 다음을 확인합니다.

  • 엔드포인트 추가/삭제
  • 요청 파라미터 변경
  • 응답 필드 변경
  • required 필드 변경
  • 상태 코드 변경
  • enum 값 변경

3. 하나의 산출물부터 생성한다

처음부터 모든 것을 자동화할 필요는 없습니다.

가장 쉬운 산출물 하나부터 연결하세요.

  • 문서 생성
  • 모의 API 생성
  • SDK 생성

스펙이 업데이트될 때 산출물도 함께 업데이트되도록 만드는 것이 핵심입니다.

4. CI 검사를 추가한다

모든 PR에서 OpenAPI 유효성을 검사합니다.

예시 흐름은 다음과 같습니다.

name: Validate OpenAPI

on:
  pull_request:
    paths:
      - "api/openapi.yaml"

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Validate OpenAPI file
        run: |
          echo "OpenAPI validation command goes here"
Enter fullscreen mode Exit fullscreen mode

사용하는 도구에 맞게 lint 또는 validation 명령을 넣으면 됩니다.

5. 계약 테스트로 루프를 닫는다

마지막으로 실행 중인 API가 커밋된 스펙과 일치하는지 테스트합니다.

이 단계가 들어가면 스펙은 단순한 문서가 아니라 강제되는 계약이 됩니다.

결론

스펙-애즈-코드는 작은 변화로 시작합니다.

하나의 OpenAPI 파일을 Git에 커밋합니다.

코드처럼 리뷰합니다.

그 파일에서 문서, 모의 API, 테스트, SDK를 생성합니다.

이렇게 하면 API 계약이 위키, 컬렉션, Markdown 문서 사이에 흩어지지 않습니다. 팀 전체가 같은 파일을 기준으로 설계하고 구현하고 검증합니다.

시각적 편집과 Git 동기화를 함께 사용하고 싶다면 Apidog의 Spec-First 모드를 사용해 보세요. OpenAPI 파일을 단일 진실 공급원으로 유지하면서 API 설계, 문서화, 테스트 워크플로를 연결할 수 있습니다.

자주 묻는 질문

“API 스펙-애즈-코드”는 “문서-애즈-코드”와 동일한가요?

동일하지는 않지만 같은 철학을 공유합니다.

문서-애즈-코드는 문서를 버전 관리 시스템에 두고 일반 개발 파이프라인으로 관리하는 방식입니다. 스펙-애즈-코드는 같은 방식을 API 계약에 적용합니다.

커밋된 OpenAPI 스펙에서 문서를 생성하면 두 방식은 자연스럽게 연결됩니다.

스펙 파일은 어떤 형식을 사용해야 하나요?

일반적으로 YAML 형식의 OpenAPI를 사용합니다.

YAML은 사람이 읽기 쉽고 PR diff가 깔끔합니다. 동시에 모의 API, 테스트, SDK 생성을 위해 기계가 파싱할 수 있습니다.

JSON도 사용할 수 있지만, 리뷰와 diff 관점에서는 YAML이 더 실용적인 경우가 많습니다.

스펙이 실제 API와 멀어지는 것을 어떻게 막을 수 있나요?

CI에 계약 테스트를 추가하세요.

실행 중인 API가 커밋된 OpenAPI 스펙과 일치하는지 검증해야 합니다. 엔드포인트가 문서화된 필드를 누락하거나, 선언되지 않은 필드를 반환하거나, 타입이 맞지 않으면 빌드가 실패해야 합니다.

이 피드백 루프가 스펙을 “희망 사항이 적힌 문서”가 아니라 실제로 강제되는 API 계약으로 만듭니다.

Top comments (0)