Swagger

Swagger는 RESTful API를 설계, 개발, 문서화, 테스트하기 위한 종합적인 도구 모음이다.
2010년 Tony Tam이 Wordnik(온라인 사전 서비스)의 API를 문서화하기 위해 최초로 개발한 이 도구는 오늘날 API 개발 생태계에서 필수적인 요소로 자리 잡았다.

Swagger는 단순한 문서화 도구가 아닌, API 개발 전체 수명주기를 지원하는 통합 플랫폼이다.
개발자들은 Swagger를 통해 API를 쉽게 이해하고, 직접 테스트하며, 클라이언트 SDK를 자동으로 생성할 수 있다. 이러한 특성으로 인해 Swagger는 API 중심 개발 방법론의 핵심 도구로 사용되고 있다.

Swagger와 OpenAPI의 관계

Swagger와 OpenAPI의 관계는 많은 개발자들이 혼동하는 부분이다.
이 둘의 관계를 명확히 이해하는 것이 중요하다:

역사적 발전

초기에 Swagger는 API를 설명하기 위한 명세(Specification)와 이를 지원하는 도구 모음 모두를 가리켰다. 그러나 2015년, Swagger 명세는 Linux Foundation 산하의 OpenAPI Initiative(OAI)에 기부되었고, 이때부터 명세 자체는 “OpenAPI 명세(OpenAPI Specification, OAS)“라는 새로운 이름을 갖게 되었다.

현재의 구분

현재의 구분은 다음과 같다:

  • OpenAPI 명세(OAS): RESTful API를 설명하기 위한 표준화된 형식이다. 이전에는 “Swagger 명세"로 알려졌다.
  • Swagger: SmartBear Software가 소유한 OpenAPI 명세를 구현하고 지원하는 도구 모음이다. 즉, Swagger는 OpenAPI를 실제로 활용할 수 있게 해주는 도구들의 브랜드 이름이다.

다시 말해, OpenAPI는 API를 설명하는 공식 명세(언어)이고, Swagger는 이 명세를 활용하여 API를 설계, 구축, 문서화하는 도구 세트이다.

Swagger 도구 에코시스템

Swagger 에코시스템은 다양한 도구로 구성되어 있으며, 각각은 API 개발 수명주기의 특정 측면을 지원한다:

Swagger Editor

Swagger Editor는 개발자가 OpenAPI 명세를 작성하고 편집할 수 있는 브라우저 기반 에디터이다.
주요 특징은 다음과 같다:

  • 실시간 검증: 작성하는 명세의 오류를 즉시 표시하고 수정 제안을 제공한다.
  • 시각적 피드백: 에디터 한쪽에는 명세를 YAML이나 JSON으로 작성하고, 다른 쪽에서는 생성된 문서의 시각적 미리보기를 제공한다.
  • 자동 완성: 명세 작성을 더 쉽게 하기 위한 자동 완성 기능을 제공한다.
  • OpenAPI 버전 지원: OpenAPI 3.0 및 Swagger 2.0 명세를 모두 지원한다.

Swagger Editor는 온라인에서 직접 사용하거나 로컬에 설치하여 사용할 수 있다.

Swagger UI

Swagger UI는 OpenAPI 명세를 시각적이고 대화형 문서로 변환하는 도구이다.
이 도구의 주요 특징은 다음과 같다:

  • 대화형 문서: 모든 API 엔드포인트, 파라미터, 응답을 시각적으로 볼 수 있다.
  • 직접 테스트: “Try it out” 기능을 통해 사용자는 문서 내에서 직접 API 호출을 실행하고 결과를 확인할 수 있다.
  • 요청/응답 시각화: 실제 요청과 응답을 시각적으로 보여주어 API의 작동 방식을 쉽게 이해할 수 있다.
  • 인증 지원: 다양한 인증 방법(API 키, OAuth 등)을 지원한다.

많은 기업들이 자사의 API 개발자 포털에 Swagger UI를 통합하여 사용자 친화적인 문서를 제공하고 있다.

Swagger Codegen

Swagger Codegen은 OpenAPI 명세에서 클라이언트 SDK, 서버 스텁, 문서를 자동으로 생성하는 도구:

  • 다양한 언어 지원: Java, Python, JavaScript, Ruby, Go, PHP, C# 등 50개 이상의 언어와 프레임워크를 지원한다.
  • 클라이언트 생성: API 소비자를 위한 클라이언트 라이브러리를 생성한다.
  • 서버 스켈레톤 생성: API 구현을 시작하기 위한 서버 코드 스켈레톤을 생성한다.
  • 커스터마이징: 템플릿을 통해 생성된 코드를 커스터마이징할 수 있다.

Swagger Codegen은 API 개발 시간을 크게 단축하고, 클라이언트-서버 간 일관성을 보장하는 데 도움이 된다.

Swagger Inspector

Swagger Inspector는 API를 빠르게 테스트하고 OpenAPI 정의를 자동으로 생성하는 도구:

  • API 엔드포인트 테스트: 모든 API 엔드포인트를 간편하게 호출하고 응답을 검증할 수 있다.
  • 자동 문서 생성: 테스트한 API 요청으로부터 OpenAPI 정의를 자동으로 생성한다.
  • 히스토리 관리: 이전 API 호출 기록을 저장하고 재사용할 수 있다.
  • Swagger UI로 내보내기: 생성된 정의를 Swagger UI로 쉽게 내보낼 수 있다.

이 도구는 특히 이미 존재하는 API의 문서화를 자동화하는 데 유용하다.

SwaggerHub

SwaggerHub는 팀을 위한 API 설계와 문서화를 위한 통합 플랫폼:

  • 협업 기능: 팀원 간 API 설계 협업을 위한 다양한 기능을 제공한다.
  • 버전 관리: API 정의의 버전을 관리하고 변경 이력을 추적한다.
  • 스타일 검증: 조직의 API 설계 가이드라인을 적용하고 검증한다.
  • 통합 기능: GitHub, Jenkins, JIRA 등의 도구와 통합된다.
  • 모의 API: API 구현 전에 모의 API를 생성하여 클라이언트 개발을 빠르게 시작할 수 있다.

SwaggerHub는 SmartBear가 제공하는 상용 서비스로, 기업 환경에서 API 개발 워크플로우를 관리하기 위한 종합적인 솔루션이다.

Swagger의 실제 구현 및 사용 방법

OpenAPI 명세 작성하기

Swagger를 활용하기 위한 첫 번째 단계는 OpenAPI 명세를 작성하는 것이다.

이를 위한 두 가지 주요 접근법이 있다:

설계 우선 접근법(Design-First Approach)

이 접근법에서는 API 구현 전에 OpenAPI 명세를 먼저 작성한다:

  1. Swagger Editor를 사용하여 API 명세를 YAML 또는 JSON 형식으로 작성한다.
  2. 작성된 명세를 검토하고 필요에 따라 수정한다.
  3. Swagger Codegen을 사용하여 서버 스텁과 클라이언트 SDK를 생성한다.
  4. 생성된 코드를 기반으로 API를 구현한다.

다음은 간단한 OpenAPI 3.0 명세의 예:

 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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
openapi: 3.0.0
info:
  title: 사용자 API
  description: 사용자 정보를 관리하는 API
  version: 1.0.0
servers:
  - url: https://api.example.com/v1
paths:
  /users:
    get:
      summary: 모든 사용자 조회
      responses:
        '200':
          description: 성공적인 응답
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/User'
    post:
      summary: 새 사용자 생성
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NewUser'
      responses:
        '201':
          description: 사용자 생성 성공
  /users/{userId}:
    get:
      summary: 특정 사용자 조회
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: 성공적인 응답
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        email:
          type: string
        createdAt:
          type: string
          format: date-time
    NewUser:
      type: object
      required:
        - name
        - email
      properties:
        name:
          type: string
        email:
          type: string
코드 우선 접근법(Code-First Approach)

이 접근법에서는 기존 API 코드에 주석이나 어노테이션을 추가하여 OpenAPI 명세를 생성한다:

  1. API 코드를 구현한다.
  2. 코드에 Swagger/OpenAPI 관련 주석이나 어노테이션을 추가한다.
  3. 도구를 사용하여 코드에서 OpenAPI 명세를 생성한다.

다음은 주요 프레임워크별 구현 예시:

Spring Boot (Java)

Spring Boot에서는 springdoc-openapi 라이브러리를 사용하여 OpenAPI 3.0 명세를 생성할 수 있다:

 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
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/users")
public class UserController {

    @Operation(summary = "모든 사용자 조회")
    @ApiResponse(responseCode = "200", description = "성공적인 응답",
                 content = @Content(mediaType = "application/json",
                 schema = @Schema(implementation = User[].class)))
    @GetMapping
    public List<User> getAllUsers() {
        // 구현 코드
    }

    @Operation(summary = "특정 사용자 조회")
    @ApiResponse(responseCode = "200", description = "사용자를 찾음")
    @ApiResponse(responseCode = "404", description = "사용자를 찾을 수 없음")
    @GetMapping("/{userId}")
    public User getUserById(
        @Parameter(description = "조회할 사용자의 ID") @PathVariable Long userId
    ) {
        // 구현 코드
    }

    @Operation(summary = "새 사용자 생성")
    @ApiResponse(responseCode = "201", description = "사용자 생성 성공")
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public User createUser(@RequestBody User user) {
        // 구현 코드
    }
}

Spring Boot 애플리케이션에 springdoc-openapi 의존성을 추가하면, 자동으로 /v3/api-docs 엔드포인트에서 OpenAPI 문서를 제공하고, /swagger-ui.html에서 Swagger UI를 사용할 수 있다.

Express (Node.js)

Express에서는 swagger-jsdocswagger-ui-express 패키지를 사용하여 OpenAPI 명세를 생성하고 문서화할 수 있다:

 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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
const express = require('express');
const swaggerJsdoc = require('swagger-jsdoc');
const swaggerUi = require('swagger-ui-express');

const app = express();

// Swagger 정의
const options = {
  definition: {
    openapi: '3.0.0',
    info: {
      title: '사용자 API',
      version: '1.0.0',
      description: '사용자 정보를 관리하는 API',
    },
    servers: [
      {
        url: 'http://localhost:3000',
      },
    ],
  },
  apis: ['./routes/*.js'], // 라우트 파일 경로
};

const specs = swaggerJsdoc(options);
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(specs));

/**
 * @swagger
 * /users:
 *   get:
 *     summary: 모든 사용자 조회
 *     responses:
 *       200:
 *         description: 성공적인 응답
 *         content:
 *           application/json:
 *             schema:
 *               type: array
 *               items:
 *                 $ref: '#/components/schemas/User'
 */
app.get('/users', (req, res) => {
  // 구현 코드
});

/**
 * @swagger
 * /users/{userId}:
 *   get:
 *     summary: 특정 사용자 조회
 *     parameters:
 *       - in: path
 *         name: userId
 *         required: true
 *         schema:
 *           type: integer
 *     responses:
 *       200:
 *         description: 사용자를 찾음
 *         content:
 *           application/json:
 *             schema:
 *               $ref: '#/components/schemas/User'
 *       404:
 *         description: 사용자를 찾을 수 없음
 */
app.get('/users/:userId', (req, res) => {
  // 구현 코드
});

/**
 * @swagger
 * components:
 *   schemas:
 *     User:
 *       type: object
 *       properties:
 *         id:
 *           type: integer
 *         name:
 *           type: string
 *         email:
 *           type: string
 */
FastAPI (Python)

FastAPI는 OpenAPI를 기본적으로 지원하므로 추가 설정 없이 자동으로 API 문서를 생성한다:

 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
43
44
45
46
47
48
49
50
51
from fastapi import FastAPI, HTTPException, Path
from pydantic import BaseModel
from typing import List, Optional
from datetime import datetime

app = FastAPI(
    title="사용자 API",
    description="사용자 정보를 관리하는 API",
    version="1.0.0"
)

class UserBase(BaseModel):
    name: str
    email: str

class UserCreate(UserBase):
    pass

class User(UserBase):
    id: int
    created_at: datetime
    
    class Config:
        orm_mode = True

@app.get("/users/", response_model=List[User], summary="모든 사용자 조회")
async def get_users():
    """
    모든 사용자의 목록을 반환합니다.
    """
    # 구현 코드

@app.get("/users/{user_id}", response_model=User, summary="특정 사용자 조회")
async def get_user(
    user_id: int = Path(..., description="조회할 사용자의 ID")
):
    """
    특정 ID를 가진 사용자의 정보를 반환합니다.
    
    - **user_id**: 조회할 사용자의 고유 ID
    """
    # 구현 코드
    # 사용자가 없으면 예외 발생
    # raise HTTPException(status_code=404, detail="User not found")

@app.post("/users/", response_model=User, status_code=201, summary="새 사용자 생성")
async def create_user(user: UserCreate):
    """
    새로운 사용자를 생성합니다.
    """
    # 구현 코드

FastAPI는 자동으로 /docs 경로에 Swagger UI를, /redoc 경로에 ReDoc 문서를 제공한다.

Swagger UI를 통한 API 테스트

Swagger UI를 사용하면 API를 쉽게 탐색하고 테스트할 수 있다.

일반적인 워크플로우는 다음과 같다:

  1. Swagger UI에 접속(일반적으로 /swagger-ui.html 또는 /docs 경로).
  2. API 엔드포인트 목록에서 테스트하려는 엔드포인트를 선택.
  3. “Try it out” 버튼을 클릭.
  4. 필요한 파라미터와 요청 본문을 입력.
  5. “Execute” 버튼을 클릭하여 API를 호출.
  6. 요청 URL, 헤더, 본문과 함께 응답 결과를 확인.

이 대화형 문서는 개발자가 API를 이해하고 테스트하는 데 매우 유용하다.

Swagger의 실제 적용 사례

기업 API 프로그램

많은 기업들이 Swagger를 API 개발 및 문서화의 핵심 도구로 사용하고 있다:

대기업 사례
  • Microsoft: Microsoft Graph API, Azure API 등 다양한 API를 Swagger/OpenAPI로 문서화하고 있다.
  • Google: Google Cloud API에 Swagger UI 기반 문서를 제공한다.
  • Amazon Web Services: AWS는 여러 서비스 API에 대해 OpenAPI 정의를 제공한다.
  • Salesforce: Salesforce API는 OpenAPI 명세를 통해 문서화되어 있다.
금융 서비스 분야

금융 산업에서는 보안과 정확한 문서화가 중요하기 때문에 Swagger가 널리 사용된다:

  • PayPal: 결제 관련 API를 Swagger로 문서화하고 있다.
  • Stripe: 결제 처리 API를 Swagger UI를 통해 제공한다.
  • 오픈뱅킹: 여러 국가의 오픈뱅킹 이니셔티브는 API 표준화를 위해 OpenAPI를 활용한다.

내부 API 거버넌스

많은 조직에서는 내부 API 관리에도 Swagger를 활용한다:

  • API 카탈로그: 모든 내부 API를 중앙 레지스트리에 등록하고 문서화
  • 설계 표준화: 일관된 API 설계를 위한 가이드라인과 검증
  • 마이크로서비스 통신: 마이크로서비스 간 통신을 위한 계약으로 OpenAPI 사용
  • 개발자 온보딩: 새로운 개발자들이 빠르게 API를 이해하고 사용할 수 있도록 지원

Swagger의 장점

Swagger는 API 개발과 관리에 여러 가지 중요한 이점을 제공한다:

개발 효율성 향상

  • 설계 중심 개발: API 설계를 먼저 완료함으로써 개발 과정이 명확해진다.
  • 코드 생성: 서버 스텁과 클라이언트 SDK를 자동으로 생성하여 개발 시간을 단축한다.
  • 병렬 개발: 프론트엔드와 백엔드 팀이 API 계약에 따라 동시에 개발을 진행할 수 있다.

문서화 자동화

  • 최신 문서 유지: API 코드와 문서가 동기화되어 항상 최신 상태를 유지한다.
  • 대화형 문서: 개발자가 쉽게 API를 이해하고 테스트할 수 있는 대화형 문서를 제공한다.
  • 일관된 형식: 모든 API에 대해 일관된 형식의 문서를 제공한다.

품질 향상

  • 설계 검증: API 설계 단계에서 오류를 조기에 발견하고 수정할 수 있다.
  • 표준화: 조직 전체에 일관된 API 설계 표준을 적용할 수 있다.
  • 테스트 자동화: API 명세를 기반으로 자동화된 테스트를 생성할 수 있다.

협업 개선

  • 명확한 커뮤니케이션: API 계약을 통해 팀 간 명확한 소통이 가능하다.
  • 이해관계자 참여: 기술적 지식이 없는 이해관계자도 API 설계를 이해하고 검토할 수 있다.
  • 피드백 루프 단축: 개발 초기 단계에서 사용자 피드백을 받을 수 있다.

Swagger 사용 시 고려사항 및 한계

Swagger의 많은 장점에도 불구하고, 사용 시 고려해야 할 몇 가지 사항과 한계가 있다:

학습 곡선

OpenAPI 명세는 광범위하고 복잡하여 완전히 익히는 데 시간이 필요하다.
특히 대규모 API의 경우 명세 작성이 까다로울 수 있다.

유지보수 부담

코드 우선 접근법을 사용할 경우, 코드와 주석을 동기화된 상태로 유지하는 것이 중요하다. 잘못된 주석이나 누락된 업데이트는 잘못된 문서로 이어질 수 있다.

설계 제약

OpenAPI는 RESTful API에 최적화되어 있어, GraphQL, gRPC, WebSocket 등 다른 유형의 API를 문서화하는 데는 제한이 있다. (이러한 API 유형에는 각각 전용 문서화 도구가 있다.)

도구 의존성

Swagger 도구 생태계에 의존하면 향후 도구가 변경되거나 사용 중단될 경우 마이그레이션 문제가 발생할 수 있다.

Swagger 도입을 위한 모범 사례

조직에서 Swagger를 효과적으로 도입하기 위한 모범 사례는 다음과 같다:

명확한 목표 설정

  • API 문서화, 코드 생성, 테스트 자동화 등 Swagger 도입의 주요 목표를 명확히 정의한다.
  • 팀이 달성하고자 하는 구체적인 성과 지표를 설정한다.

적절한 접근법 선택

  • 새로운 API 프로젝트에는 설계 우선 접근법을 고려한다.
  • 기존 API의 경우 코드 우선 접근법으로 점진적으로 문서화를 추가한다.
  • 프로젝트 성격과 팀 문화에 맞는 접근법을 선택한다.

스타일 가이드 및 템플릿 개발

  • API 설계 스타일 가이드를 개발하여 일관성을 유지한다.
  • 재사용 가능한 컴포넌트와 응답 형식을 정의한다.
  • OpenAPI 템플릿을 만들어 새로운 API 개발을 위한 시작점으로 활용한다.

개발 워크플로우 통합

  • CI/CD 파이프라인에 OpenAPI 문서 검증을 통합한다.
  • API 변경 시 자동으로 문서가 업데이트되도록 프로세스를 구성한다.
  • 코드 리뷰 과정에 API 설계 검토를 포함한다.

교육 및 지원

  • 개발자들에게 OpenAPI와 Swagger 도구에 대한 교육을 제공한다.
  • 팀 내 Swagger 전문가를 양성하여 다른 멤버들을 지원하도록 한다.
  • 내부 문서와 예제를 통해 모범 사례를 공유한다.

용어 정리

용어설명

참고 및 출처