본문 바로가기

Software Engineering

OpenAPI Specification(OAS) : API 문서화의 게임 체인저

오늘은 API 개발과 문서화를 혁신적으로 바꿔놓은 **OpenAPI Specification(OAS)**에 대해 깊이 있게 알아보겠습니다.

혹시 아직도 API 문서를 Word나 Notion에서 수동으로 작성하고 계신가요? 그렇다면 이 글이 여러분의 개발 인생을 바꿔드릴 수도 있습니다! 

🤔 OAS가 뭔데?

OpenAPI Specification(이전에는 Swagger Specification이라고 불렸음)은 REST API를 기술하기 위한 표준 규격입니다. 쉽게 말해서, API가 어떻게 동작하는지를 사람과 기계가 모두 이해할 수 있는 형태로 문서화하는 방법이에요.

🏗️ 건축 설계도면 : 건물 = OAS 스펙 : API

건축가가 설계도면을 보고 건물의 구조를 파악하듯이, 개발자는 OAS 문서를 보고 API의 모든 것을 이해할 수 있습니다.

📊 OAS의 구조 개념도

┌─────────────────────────────────────┐
│           OpenAPI Document          │
├─────────────────────────────────────┤
│  📋 Info (제목, 버전, 설명)           │
├─────────────────────────────────────┤
│  🌍 Servers (API 서버 정보)          │
├─────────────────────────────────────┤
│  🛣️  Paths (API 엔드포인트들)         │
│    ├─ GET /users                   │
│    ├─ POST /users                  │
│    └─ PUT /users/{id}              │
├─────────────────────────────────────┤
│  🧩 Components (재사용 가능한 요소)   │
│    ├─ Schemas (데이터 모델)         │
│    ├─ Parameters (매개변수)         │
│    └─ Responses (응답 형식)         │
└─────────────────────────────────────┘

📝 실전 OAS 작성해보기

자, 이제 실제로 간단한 사용자 관리 API를 OAS로 작성해볼까요?

기본 구조 설정

openapi: 3.0.3
info:
  title: 사용자 관리 API
  description: 간단한 사용자 CRUD API 예제
  version: 1.0.0
  contact:
    name: API 지원팀
    email: support@example.com

servers:
  - url: https://api.example.com/v1
    description: 프로덕션 서버
  - url: https://staging-api.example.com/v1
    description: 스테이징 서버

API 엔드포인트 정의

paths:
  /users:
    get:
      summary: 사용자 목록 조회
      description: 등록된 모든 사용자의 목록을 반환합니다.
      parameters:
        - name: page
          in: query
          description: 페이지 번호
          required: false
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          description: 페이지당 결과 수
          required: false
          schema:
            type: integer
            default: 10
            maximum: 100
      responses:
        '200':
          description: 성공적으로 사용자 목록을 반환
          content:
            application/json:
              schema:
                type: object
                properties:
                  users:
                    type: array
                    items:
                      $ref: '#/components/schemas/User'
                  pagination:
                    $ref: '#/components/schemas/Pagination'

    post:
      summary: 새 사용자 생성
      description: 새로운 사용자를 시스템에 등록합니다.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateUserRequest'
      responses:
        '201':
          description: 사용자가 성공적으로 생성됨
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '400':
          description: 잘못된 요청 데이터
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /users/{userId}:
    get:
      summary: 특정 사용자 조회
      parameters:
        - name: userId
          in: path
          required: true
          description: 사용자 ID
          schema:
            type: integer
            format: int64
      responses:
        '200':
          description: 사용자 정보 반환
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '404':
          description: 사용자를 찾을 수 없음
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

재사용 가능한 컴포넌트 정의

components:
  schemas:
    User:
      type: object
      required:
        - id
        - email
        - name
      properties:
        id:
          type: integer
          format: int64
          description: 사용자 고유 ID
          example: 12345
        email:
          type: string
          format: email
          description: 사용자 이메일 주소
          example: "john.doe@example.com"
        name:
          type: string
          description: 사용자 이름
          example: "홍길동"
        createdAt:
          type: string
          format: date-time
          description: 계정 생성 시간
          example: "2023-12-01T10:30:00Z"

    CreateUserRequest:
      type: object
      required:
        - email
        - name
        - password
      properties:
        email:
          type: string
          format: email
          example: "new.user@example.com"
        name:
          type: string
          minLength: 2
          maxLength: 50
          example: "김개발"
        password:
          type: string
          minLength: 8
          description: 최소 8자 이상의 비밀번호
          example: "securePassword123!"

    Pagination:
      type: object
      properties:
        currentPage:
          type: integer
          example: 1
        totalPages:
          type: integer
          example: 10
        totalItems:
          type: integer
          example: 95
        itemsPerPage:
          type: integer
          example: 10

    Error:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: 에러 코드
          example: "VALIDATION_ERROR"
        message:
          type: string
          description: 에러 메시지
          example: "이메일 형식이 올바르지 않습니다."
        details:
          type: array
          items:
            type: string
          description: 상세 에러 정보

🔄 OAS 활용 워크플로우

🎯 API 설계 단계
    ↓
📝 OAS 문서 작성
    ↓
🤖 코드 생성 (서버/클라이언트)
    ↓
📚 문서 자동 생성
    ↓
🧪 테스트 케이스 생성
    ↓
🚀 배포 및 모니터링

💡 OAS 활용 도구들

1. Swagger UI





    
 

        SwaggerUIBundle({
            url: './openapi.yaml',
            dom_id: '#swagger-ui'
        });
    

2. 코드 생성 예시

# Java Spring Boot 서버 코드 생성
openapi-generator generate \
  -i openapi.yaml \
  -g spring \
  -o ./server-code

# JavaScript 클라이언트 코드 생성
openapi-generator generate \
  -i openapi.yaml \
  -g javascript \
  -o ./client-code

✅ OAS의 장점들

🎯 1. 일관성 있는 API 설계

  • 표준화된 방식으로 API를 문서화
  • 팀 전체가 같은 규칙으로 작업 가능
  • API 버전 관리가 체계적

🤖 2. 자동화의 힘

OAS 문서 → 서버 코드 자동 생성
OAS 문서 → 클라이언트 SDK 자동 생성
OAS 문서 → 테스트 케이스 자동 생성
OAS 문서 → API 문서 자동 생성

🔄 3. Design-First 개발 가능

  • 구현 전에 API 설계를 완성
  • 프론트엔드와 백엔드 병렬 개발 가능
  • 스테이크홀더와의 명확한 소통

🧪 4. 테스트 자동화

// Jest를 사용한 OAS 기반 테스트 예시
const request = require('supertest');
const app = require('../app');

describe('GET /users', () => {
  test('should return users list', async () => {
    const response = await request(app)
      .get('/users')
      .expect(200)
      .expect('Content-Type', /json/);
    
    // OAS 스키마 검증
    expect(response.body).toHaveProperty('users');
    expect(response.body).toHaveProperty('pagination');
  });
});

📊 5. 모니터링과 분석

  • API 사용 패턴 분석 가능
  • 성능 모니터링 기준점 제공
  • 버전별 사용률 추적 가능

 

⚠️ OAS의 단점

😰 1. 초기 학습 곡선

  • YAML/JSON 문법 숙지 필요
  • OpenAPI 3.0 스펙 이해 필요
  • 도구들의 사용법 학습 필요

📝 2. 문서 유지보수 부담

❌ 잘못된 접근:
코드 변경 → 문서 업데이트 깜빡 → 문서와 실제 API 불일치

✅ 올바른 접근:
코드 변경 → 자동 문서 업데이트 → CI/CD 파이프라인 통합

3. 성능 고려사항

  • 대용량 API의 경우 OAS 파일이 거대해질 수 있음
  • 런타임에서 스키마 검증 시 성능 오버헤드
  • 복잡한 API는 문서 로딩 시간 증가

🔧 4. 툴링 의존성

  • 특정 도구에 종속될 위험
  • 도구 간 호환성 문제 가능
  • 커스터마이징의 한계

 

🎯 OAS 도입 시 Best Practice

1. 점진적 도입

# 처음엔 간단하게 시작
openapi: 3.0.3
info:
  title: My API
  version: 1.0.0
paths:
  /health:
    get:
      responses:
        '200':
          description: OK

2. CI/CD 통합

# GitHub Actions 예시
name: API Documentation
on: [push]
jobs:
  docs:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Generate API docs
        run: |
          npx swagger-codegen generate -i openapi.yaml -l html2 -o docs/
      - name: Deploy to GitHub Pages
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./docs

3. 스키마 검증 자동화

// Express.js에서 OAS 스키마 검증
const OpenApiValidator = require('express-openapi-validator');

app.use(
  OpenApiValidator.middleware({
    apiSpec: './openapi.yaml',
    validateRequests: true,
    validateResponses: true
  })
);

🚀 마무리

OAS는 단순한 문서화 도구를 넘어서 API 개발의 전체 라이프사이클을 혁신하는 강력한 도구입니다.

초기 학습 비용이 있지만, 일단 익숙해지면 개발 효율성과 코드 품질이 획기적으로 향상됩니다.

특히 마이크로서비스 아키텍처나 대규모 팀에서 작업할 때 그 진가를 발휘합니다.

API 간의 계약을 명확히 하고, 자동화를 통해 휴먼 에러를 줄이며, 개발자 경험을 크게 개선할 수 있어요.

 

 

📚 더 알아보기