[API Design] OpenAPI / Swagger: 스펙, 코드 생성, contract testing
OpenAPI Swagger, OpenAPI, Swagger, OAS, Swagger UI, Redoc, contract testing, API-first
정의
OpenAPI Specification (OAS) 은 REST API 를 기술하는 YAML/JSON 형식. 옛 이름 Swagger. 2017 부터 OpenAPI Initiative (Linux Foundation) 관리.
핵심 가치:
- 사람이 읽는 문서 (Swagger UI, Redoc)
- 클라이언트 SDK 자동 생성 (다국어)
- 서버 stub 생성
- contract testing (스펙 ↔ 실제 응답 검증)
- mock server
기본 구조
openapi: 3.1.0
info:
title: Shop API
version: 1.0.0
servers:
- url: https://api.example.com/v1
paths:
/items/{id}:
get:
summary: Get item by ID
parameters:
- in: path
name: id
required: true
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Item'
'404':
description: Not found
components:
schemas:
Item:
type: object
required: [id, name, price]
properties:
id:
type: string
name:
type: string
price:
type: integer
minimum: 0
워크플로 (API-first)
flowchart LR
Design[스펙 작성<br/>openapi.yaml] --> Review[리뷰]
Review --> Gen[코드 생성]
Gen --> Server[서버 stub]
Gen --> Client[클라이언트 SDK]
Gen --> Mock[Mock server]
Gen --> Docs[문서 UI]
Server --> Impl[실제 구현]
Impl --> Test[contract test]
Test -->|스펙 위반| Design
OpenAPI 3.1 의 주요 기능
| 기능 | 의미 |
|---|---|
$ref | 정의 재사용 |
components.schemas | 모델 분리 |
components.parameters | 공통 파라미터 |
components.responses | 공통 응답 |
components.securitySchemes | 인증 방식 |
oneOf / anyOf / allOf | 다형성 |
discriminator | type 필드로 분기 |
links | HATEOAS 표현 |
| Webhooks (3.1+) | 비동기 콜백 |
인증 표현
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
apiKeyAuth:
type: apiKey
in: header
name: X-API-Key
oauth2:
type: oauth2
flows:
authorizationCode:
authorizationUrl: https://example.com/oauth/authorize
tokenUrl: https://example.com/oauth/token
scopes:
read:items: Read items
write:items: Modify items
security:
- bearerAuth: []
코드 생성 (openapi-generator)
# TypeScript axios 클라이언트
openapi-generator-cli generate \
-i openapi.yaml \
-g typescript-axios \
-o ./generated/client
# Spring Boot 서버 stub
openapi-generator-cli generate \
-i openapi.yaml \
-g spring \
-o ./generated/server
지원 언어 수십 가지. 모든 주요 stack 의 클라이언트 SDK 가 자동.
Contract Testing
스펙과 실제 응답 이 일치하는지 검증:
flowchart LR
Spec[openapi.yaml] -->|검증| Validator
Server -->|실제 응답| Validator
Validator -->|불일치| Fail[테스트 실패]
Validator -->|일치| Pass[테스트 통과]
도구: Schemathesis, Dredd, Prism.
# Schemathesis 로 spec 기반 fuzzing
schemathesis run openapi.yaml --url=https://api.example.com
spec 의 모든 endpoint + 가능한 입력 조합 자동 생성 + 응답 검증.
문서 UI
| 도구 | 특징 |
|---|---|
| Swagger UI | 표준, try it out 패널 |
| Redoc | 세련된 정적 문서, 사이드 nav |
| Scalar | 신예, dark mode + 빠름 |
| Stoplight Elements | 임베드 친화 |
버전 역사
| 버전 | 출시 | 핵심 변화 |
|---|---|---|
| Swagger 2.0 | 2014 | swagger: "2.0" 키. host + basePath + schemes 조합으로 서버 URL 표현. |
| OAS 3.0 | 2017 | OpenAPI Initiative 첫 리브랜딩. servers 배열, components, requestBody 도입. $ref 외부 파일 참조 지원. |
| OAS 3.1 | 2021 | JSON Schema 2020-12 완전 호환. webhooks 최상위 필드. nullable 제거 → type: ["string", "null"]. $vocabulary. |
IMPORTANT
2026 기준 신규 프로젝트는 OAS 3.1 권장. openapi-generator, Redoc, Swagger UI, Scalar 모두 3.1 지원. 기존 Swagger 2.0 스펙은 swagger-converter 로 자동 변환 가능.
CI/CD 파이프라인 통합
API-first 워크플로는 스펙이 항상 구현과 동기화되어야 합니다. CI 에 3 단계로 포함:
# .github/workflows/api-contract.yml
name: API Contract
on: [push, pull_request]
jobs:
contract:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Lint OpenAPI spec
run: npx @redocly/cli lint openapi.yaml
- name: Run contract tests
run: |
pip install schemathesis
schemathesis run openapi.yaml \
--url=http://localhost:8080 \
--checks=all
- name: Generate TypeScript SDK
run: |
npx @openapitools/openapi-generator-cli generate \
-i openapi.yaml -g typescript-axios -o ./sdk
| 단계 | 도구 | 실패 의미 |
|---|---|---|
| Lint | Redocly CLI | 스펙 문법 오류 |
| Contract test | Schemathesis | 서버 응답이 스펙 위반 |
| SDK 생성 | openapi-generator | SDK 타입 불일치 조기 발견 |
$ref 설계 팁
모든 스키마를 components/schemas 에 정의하고 $ref 로 재사용합니다.
# 나쁜 예: inline 반복 정의
paths:
/orders:
post:
requestBody:
content:
application/json:
schema:
type: object
properties:
item_id: {type: string}
qty: {type: integer}
# 좋은 예: components 에 정의, $ref 로 재사용
components:
schemas:
OrderRequest:
type: object
required: [item_id, qty]
properties:
item_id: {type: string}
qty:
type: integer
minimum: 1
paths:
/orders:
post:
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/OrderRequest'
$ref 재사용의 이점: SDK 생성 시 공유 타입으로 자동 추출, 스키마 수정 한 곳에서 완결.
OpenAPI 의 한계
flowchart TD
Strong[잘 표현되는 것] --> CRUD[CRUD REST]
Strong --> Webhook[webhook 페이로드]
Strong --> Type[type-safe 모델]
Weak[표현 약한 것] --> StateMachine[복잡한 상태 머신]
Weak --> Realtime["실시간 (WS, SSE)"]
Weak --> BinaryProto[바이너리 프로토콜]
Weak --> Workflow[multi-step workflow]
gRPC 는 proto, GraphQL 은 SDL, AsyncAPI 는 비동기 / 이벤트 의 OpenAPI 등가체.
흔한 함정
WARNING
- 스펙과 실제 응답 의 표류 = contract test 없으면 문서가 거짓말. CI 에 포함.
- 모든 응답을 200 OK 로 spec = 4xx/5xx 도 명시. 클라이언트 SDK 의 error type 이 정확해짐.
oneOf의 없는 discriminator = 클라이언트가 어떤 타입인지 구분 못함. 항상 discriminator 명시.- 너무 늦게 spec 작성 = 코드부터 작성 후 spec 은 retrospective spec 으로 문서 정확도 떨어짐. API-first 가 정통.
관련 위키
- REST API Design
- API 버전 관리 (URL vs Header vs Media Type 전략)
- gRPC (proto 기반 대안)
- GraphQL (SDL 기반 대안)
- JWT (인증 스키마 표현)
- AWS API Gateway (클라우드 게이트웨이에서 OpenAPI import 지원)
이 글의 용어 (6개)
- [API Design] API Versioning: URL / Header / Date 비교api-design
- 정의 API Versioning 은 breaking change 를 클라이언트에 강요 없이 호환성을 유지하는 전략. 잘못 잡으면 모든 클라이언트 동시 마이그레이션 강요. 무엇이 …
- [API Design] GraphQL: 단일 endpoint, N+1, persisted queriesapi-design
- 정의 GraphQL (Facebook, 2015) 은 클라이언트가 필요한 필드만 명시 하는 query language + 런타임. 단일 endpoint, typed schema,…
- [API Design] REST API: 원칙, 자원 모델링, HATEOAS, 버전 관리api-design
- 정의 REST (Representational State Transfer) 는 Roy Fielding 의 2000년 박사논문에서 정립된 분산 시스템 아키텍처 스타일. HTTP 의…
- [Auth] JWT: 구조, 서명, 만료, refresh tokenauth-security
- 정의 JWT (JSON Web Token) (RFC 7519) 은 base64url 인코딩된 JSON + 서명 형태의 self-contained token. 서버가 세션 저장 없…
- [AWS] API Gateway: REST/HTTP/WebSocket API 관리cloud
- 정의 AWS API Gateway 는 REST / HTTP / WebSocket API 를 관리하는 완전관리형 서비스. 인증, 스로틀링, 캐싱, 요청/응답 변환, 로깅을 단일 서…
- [Network] gRPC: HTTP/2 + Protobuf, 4가지 streaming 패턴network
- 정의 gRPC 는 HTTP/2 위에서 Protobuf 직렬화 로 동작하는 고성능 RPC 프레임워크. Google 내부 Stubby 의 오픈소스 후계. 핵심 4가지: 1. Prot…
💬 댓글