OpenAPI 사양(OpenAPI Specification, OAS)

OpenAPI 사양(OpenAPI Specification, OAS)은 REST API를 설계, 문서화 및 표준화하기 위한 언어에 구애받지 않는 정의 형식이다.

Swagger와 OpenAPI의 개념과 역사

Swagger의 탄생

Swagger는 2010년 Tony Tam에 의해 시작된 프로젝트로, RESTful API를 설계, 구축, 문서화, 소비하기 위한 오픈 소스 프레임워크이다. 초기에는 Wordnik이라는 온라인 사전 API를 문서화하기 위해 개발되었으나, 빠르게 API 개발 커뮤니티 내에서 인기를 얻었다.

OpenAPI로의 전환

2015년, Swagger 사양은 Linux Foundation 산하의 OpenAPI Initiative(OAI)에 기부되었고, Swagger 사양은 “OpenAPI 사양(OpenAPI Specification, OAS)“이라는 새로운 이름을 갖게 되었다. 이러한 전환은 사양을 더 중립적이고 산업 표준으로 발전시키기 위한 움직임이었다.

명칭 혼동 해소

현재:

  • OpenAPI 사양(OAS): RESTful API를 설명하는 데 사용되는 표준 사양이다.
  • Swagger: SmartBear Software가 소유한 OpenAPI 사양 구현을 위한 도구 모음이다. 이제 Swagger는 OpenAPI 사양을 지원하는 도구의 브랜드 이름이다.

많은 사람들이 여전히 “Swagger"라는 용어를 사용하지만, 공식적으로는 사양 자체는 “OpenAPI 사양"이라고 불린다.

OpenAPI 사양(OAS)의 이해

OpenAPI 사양은 RESTful API를 기술하기 위한 언어에 구애받지 않는 표준 인터페이스이다.
이는 인간과 컴퓨터 모두가 API의 기능을 이해할 수 있게 해주며, 구현 논리에 접근하지 않고도 가능하다.

OAS의 주요 버전

  • Swagger 1.0 (2011년) - 최초 릴리스
  • Swagger 2.0 (2014년) - 주요 업데이트, 대중적으로 채택이 되었으며 JSON과 YAML 형식을 지원한다.
  • OpenAPI 3.0 (2017년) - 이름 변경 및 중요한 개선사항 추가
  • OpenAPI 3.1 (2021년) - JSON Schema 호환성 향상 및 새로운 기능 추가

OAS 문서 구조

OpenAPI 사양 문서는 일반적으로 JSON 또는 YAML 형식으로 작성되며 다음과 같은 주요 섹션을 포함한다:

  1. 메타데이터(Metadata): API의 제목, 버전, 설명, 연락처 정보 등을 포함한다.
  2. 서버(Servers): API가 호스팅되는 기본 URL을 정의한다.
  3. 경로(Paths): API의 엔드포인트와 지원되는 HTTP 메서드를 정의한다.
  4. 컴포넌트(Components): 스키마(데이터 모델), 파라미터, 응답, 보안 정의 등 재사용 가능한 객체를 정의한다.
  5. 보안(Security): API에서 사용하는 인증 메커니즘을 설명한다.
  6. 태그(Tags): API 작업을 논리적인 그룹으로 분류한다.

OpenAPI 사양의 주요 개념

정의 및 목적

OpenAPI 사양은 API의 모든 측면을 기술할 수 있는 형식화된 방법을 제공한다.

이는 기계가 읽을 수 있는 인터페이스 파일로, API의 다음 요소들을 정의한다:

  • 사용 가능한 엔드포인트(예: /users)
  • 각 엔드포인트에 대한 작업(GET, POST, PUT, DELETE 등)
  • 각 작업의 입력 매개변수
  • 각 작업의 출력 응답
  • 인증 방법
  • 연락처 정보, 라이선스, 이용 약관 등

문서 구조

OpenAPI 3.0 문서는 YAML 또는 JSON 형식으로 작성되며 다음과 같은 주요 섹션으로 구성된다:

 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
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'
components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string

OpenAPI 사양의 핵심 요소

메타데이터 (Info 객체)

API에 대한 기본 정보를 제공한다:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
info:
  title: 사용자 API
  description: 사용자 관리를 위한 API
  termsOfService: https://example.com/terms/
  contact:
    name: API 지원팀
    url: https://example.com/support
    email: support@example.com
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html
  version: 1.0.0

서버 정보

API 서버의 기본 URL을 정의한다:

1
2
3
4
5
6
7
servers:
  - url: https://development.example.com/v1
    description: 개발 서버
  - url: https://staging.example.com/v1
    description: 스테이징 서버
  - url: https://api.example.com/v1
    description: 운영 서버

경로 및 작업

API 엔드포인트 및 HTTP 메서드를 정의한다:

 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
paths:
  /users:
    get:
      summary: 사용자 목록 조회
      description: 시스템의 모든 사용자 목록을 반환합니다
      parameters:
        - name: limit
          in: query
          description: 반환할 최대 항목 수
          schema:
            type: integer
            format: int32
      responses:
        '200':
          description: 성공적인 응답
    post:
      summary: 새 사용자 생성
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/User'
      responses:
        '201':
          description: 사용자 생성됨

매개변수

API 요청에 사용되는 매개변수를 정의한다:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
parameters:
  - name: userId
    in: path
    required: true
    description: 조회할 사용자의 ID
    schema:
      type: integer
  - name: includeDeleted
    in: query
    description: 삭제된 사용자도 포함할지 여부
    schema:
      type: boolean
      default: false

매개변수 위치(in) 값:

  • path: URL 경로의 일부(예: /users/{userId})
  • query: URL 쿼리 매개변수(예: /users?limit=10)
  • header: HTTP 헤더
  • cookie: 쿠키

3.5 요청 본문

API 요청에 포함될 수 있는 데이터를 정의한다:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
requestBody:
  description: 생성할 사용자 정보
  required: true
  content:
    application/json:
      schema:
        $ref: '#/components/schemas/User'
    application/xml:
      schema:
        $ref: '#/components/schemas/User'

응답

API가 반환할 수 있는 응답을 정의한다:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
responses:
  '200':
    description: 성공적인 응답
    content:
      application/json:
        schema:
          $ref: '#/components/schemas/UserArray'
  '400':
    description: 잘못된 요청
    content:
      application/json:
        schema:
          $ref: '#/components/schemas/Error'
  '404':
    description: 사용자를 찾을 수 없음

컴포넌트 및 스키마

재사용 가능한 객체를 정의한다:

 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
components:
  schemas:
    User:
      type: object
      required:
        - id
        - name
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
        email:
          type: string
          format: email
    Error:
      type: object
      properties:
        code:
          type: integer
        message:
          type: string
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

보안 정의

API의 보안 요구사항을 정의한다:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
security:
  - bearerAuth: []
  - apiKeyAuth: []

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
    apiKeyAuth:
      type: apiKey
      in: header
      name: X-API-KEY

OpenAPI 사양(OAS)의 주요 버전 비교

Swagger 2.0 / OpenAPI 2.0

Swagger 2.0은 2014년에 출시되었으며, 이후 OpenAPI Initiative가 형성되면서 OpenAPI 2.0으로 이름이 변경되었다.

주요 특징
  • JSON과 YAML 형식 모두 지원
  • 기본 문서 구조: info, paths, definitions, parameters, responses, securityDefinitions 등
  • API 경로, 매개변수, 응답, 모델 정의 기능 제공
  • 인증 메커니즘 정의 가능 (basic, apiKey, oauth2)
예시 구조
 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
swagger: '2.0'
info:
  title: 샘플 API
  version: '1.0.0'
paths:
  /users:
    get:
      summary: 사용자 목록 조회
      responses:
        200:
          description: 성공적인 응답
          schema:
            $ref: '#/definitions/Users'
definitions:
  Users:
    type: array
    items:
      $ref: '#/definitions/User'
  User:
    type: object
    properties:
      id:
        type: integer
      name:
        type: string
한계점
  • 복잡한 데이터 구조 표현의 어려움
  • 재사용 가능한 요소 정의에 제한
  • 문서 구조가 다소 경직됨

OpenAPI 3.0

2017년 출시된 OpenAPI 3.0은 Swagger 2.0/OpenAPI 2.0에서 상당한 발전을 이루었다.

주요 변경사항
  1. 구조적 변화:
    • definitionscomponents로 대체됨
    • components 아래에 schemas, responses, parameters, examples, requestBodies, headers, securitySchemes 등이 포함됨
  2. 향상된 기능:
    • 요청 본문(Request Body) 개념 도입
    • 콘텐츠 협상(Content Negotiation) 지원 강화
    • 예제(Examples) 지원 향상
    • 링크(Links) 개념 도입으로 응답과 후속 요청 간의 관계 정의 가능
    • 콜백(Callbacks) 기능 추가
  3. 인증 메커니즘 개선:
    • OpenID Connect 지원
    • 다양한 OAuth 2.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
openapi: '3.0.0'
info:
  title: 샘플 API
  version: '1.0.0'
paths:
  /users:
    get:
      summary: 사용자 목록 조회
      responses:
        '200':
          description: 성공적인 응답
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Users'
components:
  schemas:
    Users:
      type: array
      items:
        $ref: '#/components/schemas/User'
    User:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
주요 이점
  • 코드 재사용성 향상
  • 더 명확한 API 문서화
  • 복잡한 API 워크플로우 표현 가능
  • 더 풍부한 미디어 타입 지원

OpenAPI 3.1

2021년 2월에 출시된 OpenAPI 3.1은 JSON Schema 사양과의 호환성을 크게 개선했다.

주요 변경사항
  1. JSON Schema 호환성:
    • JSON Schema Draft 2020-12와 호환
    • nullable 속성 대신 type: [string, 'null']과 같은 타입 배열 사용
  2. 새로운 기능:
    • 웹훅(Webhooks) 지원 강화
    • 경로템플릿(Path Templates)에서 여러 경로 매개변수 지원
    • discriminator 개선으로 다형성 더 잘 지원
  3. 문서 구조 개선:
    • 최상위 레벨에 webhooks 섹션 추가
    • examples 섹션의 구조 변경
    • 매개변수와 응답 헤더에서 content 사용 가능
예시 구조
 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
openapi: '3.1.0'
info:
  title: 샘플 API
  version: '1.0.0'
paths:
  /users:
    get:
      summary: 사용자 목록 조회
      responses:
        '200':
          description: 성공적인 응답
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Users'
webhooks:
  newUser:
    post:
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/User'
      responses:
        '200':
          description: 성공적인 웹훅 처리
components:
  schemas:
    Users:
      type: array
      items:
        $ref: '#/components/schemas/User'
    User:
      type: object
      properties:
        id:
          type: integer
        name:
          type: [string, 'null']  # nullable 대신 타입 배열 사용
주요 이점
  • JSON Schema와의 완전한 호환성으로 기존 JSON Schema 도구 활용 가능
  • 웹훅 설계의 표준화
  • 더 유연한 타입 시스템
  • 더 나은 다형성 지원

버전별 비교표

기능Swagger 2.0 / OpenAPI 2.0OpenAPI 3.0OpenAPI 3.1
릴리스 시기2014년2017년2021년
기본 구조swagger, info, paths, definitionsopenapi, info, paths, componentsopenapi, info, paths, components, webhooks
모델 정의 위치definitionscomponents/schemascomponents/schemas
nullable 지원xnullable: truetype: [string, ’null']
요청 본문parameter in: bodyrequestBodyrequestBody
콘텐츠 협상consumes/producescontent 객체content 객체
예제 지원제한적향상됨더욱 향상됨
링크 지원xlinkslinks
콜백 지원xcallbackscallbacks
웹훅 전용 섹션xxwebhooks
JSON Schema 호환성부분적부분적완전 (Draft 2020-12)

마이그레이션 시 고려사항

OpenAPI 2.0에서 3.0으로 마이그레이션
  1. definitions, parameters, responses 등을 components 아래로 이동
  2. consumesproducescontent 객체로 대체
  3. in: body 매개변수를 requestBody로 변환
  4. 응답 스키마를 content 객체 내로 이동
OpenAPI 3.0에서 3.1로 마이그레이션
  1. nullable: truetype 배열로 변환 (예: type: [string, 'null'])
  2. 웹훅 정의를 callbacks에서 최상위 webhooks 섹션으로 이동 가능
  3. JSON Schema와의 호환성 확인
OpenAPI 3.0 vs. 3.1의 주요 차이점

OpenAPI 3.1은 2021년 2월에 출시된 가장 최신 버전으로, 다음과 같은 중요한 변경사항이 있다:

  1. JSON Schema 호환성: 완전한 JSON Schema 2020-12 호환성 추가
  2. 새로운 데이터 타입: null 타입과 여러 타입을 조합한 배열 지원
  3. 웹훅(Webhooks): API가 클라이언트에게 보내는 요청을 정의하는 새로운 최상위 요소
  4. 경로템플릿(Path Templates): URL 템플릿을 더 유연하게 정의
  5. 예제 향상: 다양한 예제 제공 방법 개선

예시:

1
2
3
4
5
6
7
8
# OpenAPI 3.0
schema:
  type: object
  nullable: true

# OpenAPI 3.1
schema:
  type: [object, "null"]

OpenAPI와 관련 API 표준 비교

OpenAPI vs. API Blueprint

측면OpenAPIAPI Blueprint
형식YAML/JSONMarkdown
도구 생태계매우 넓음제한적
학습 곡선중간낮음 (마크다운 기반)
표현력높음중간
채택률매우 높음중간

OpenAPI vs. RAML

측면OpenAPIRAML
형식YAML/JSONYAML
초점전체 API 수명 주기API 설계
재사용성컴포넌트트레이트와 리소스 타입
채택률매우 높음중간
도구 지원넓음제한적

OpenAPI vs. gRPC

측면OpenAPIgRPC
프로토콜HTTP/RESTHTTP/2
IDLJSON/YAMLProtocol Buffers
성능표준 HTTP최적화된 바이너리
사용 사례범용 웹 API마이크로서비스 내부 통신
문서화내장제한적

OpenAPI vs. GraphQL

측면OpenAPIGraphQL
데이터 가져오기엔드포인트별클라이언트 요청별
버전 관리명시적진화적
오버페칭/언더페칭발생 가능최소화
문서화명시적스키마에서 생성
사용 사례범용 API데이터 중심 API

OpenAPI 사양 심화 주제

링크와 콜백

OpenAPI 3.0에서 도입된 링크와 콜백은 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
paths:
  /users:
    post:
      # …
      responses:
        '201':
          description: 사용자 생성됨
          links:
            GetUserById:
              operationId: getUserById
              parameters:
                userId: '$response.body#/id'
              description: '새로 생성된 사용자 정보 조회'

  /webhooks/orderStatus:
    post:
      # …
      callbacks:
        orderStatusChanged:
          '{$request.body#/callbackUrl}':
            post:
              requestBody:
                content:
                  application/json:
                    schema:
                      $ref: '#/components/schemas/OrderStatus'
              responses:
                '200':
                  description: 성공적인 콜백 처리

고급 스키마 기능

OpenAPI 3.1은 더 강력한 데이터 모델링 기능을 제공한다:

 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
components:
  schemas:
    AdvancedUser:
      type: object
      discriminator:
        propertyName: userType
        mapping:
          admin: '#/components/schemas/AdminUser'
          standard: '#/components/schemas/StandardUser'
      properties:
        id:
          type: integer
        username:
          type: string
        userType:
          type: string
          enum: [admin, standard]
      
    AdminUser:
      allOf:
        - $ref: '#/components/schemas/AdvancedUser'
        - type: object
          properties:
            permissions:
              type: array
              items:
                type: string
    
    StandardUser:
      allOf:
        - $ref: '#/components/schemas/AdvancedUser'
        - type: object
          properties:
            memberSince:
              type: string
              format: date

JSON Schema 연동

OpenAPI 3.1은 JSON Schema 2020-12와 완전히 호환된다:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
components:
  schemas:
    ComplexObject:
      type: [object, "null"]  # 유니온 타입 (3.1에서 지원)
      properties:
        name:
          type: string
        tags:
          type: array
          items:
            type: string
          uniqueItems: true
          minItems: 1
        metadata:
          type: object
          additionalProperties:
            type: [string, number, boolean]  # 유니온 타입

실용적인 API 설계 지침

일관된 리소스 명명 규칙

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 권장
paths:
  /users:                 # 복수형 사용
  /users/{userId}:        # 복수형 컬렉션, 단수형 식별자
  /users/{userId}/orders: # 중첩된 관계

# 비권장
paths:
  /user:                # 단수형
  /get-users:           # 동사 사용
  /users/{userId}/order: # 일관성 없는 복수형/단수형

적절한 상태 코드 사용

 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
paths:
  /users:
    get:
      responses:
        '200':
          description: 사용자 목록 검색 성공
    post:
      responses:
        '201':
          description: 사용자 생성 성공
        '400':
          description: 잘못된 사용자 데이터
        '409':
          description: 중복된 사용자
  /users/{userId}:
    get:
      responses:
        '200':
          description: 사용자 찾음
        '404':
          description: 사용자를 찾을 수 없음
    put:
      responses:
        '200':
          description: 사용자 업데이트 성공
        '404':
          description: 사용자를 찾을 수 없음
    delete:
      responses:
        '204':
          description: 사용자 삭제 성공 (콘텐츠 없음)
        '404':
          description: 사용자를 찾을 수 없음

효과적인 쿼리 매개변수 디자인

 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
paths:
  /products:
    get:
      parameters:
        - name: category
          in: query
          description: 제품 카테고리로 필터링
          schema:
            type: string
        - name: sort
          in: query
          description: 정렬 필드
          schema:
            type: string
            enum: [price, name, rating]
        - name: order
          in: query
          description: 정렬 순서
          schema:
            type: string
            enum: [asc, desc]
            default: asc
        - name: page
          in: query
          description: 페이지 번호
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: limit
          in: query
          description: 페이지당 항목 수
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20

실제 구현 예제: 사용자 API

다음은 사용자 관리 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
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
openapi: 3.0.3
info:
  title: 사용자 관리 API
  description: 사용자 계정 생성, 조회, 수정 및 삭제를 위한 API
  version: 1.0.0
  contact:
    name: API 지원팀
    email: api@example.com

servers:
  - url: https://api.example.com/v1
    description: 운영 서버
  - url: https://staging-api.example.com/v1
    description: 스테이징 서버

tags:
  - name: 사용자
    description: 사용자 관리 작업
  - name: 인증
    description: 인증 관련 작업

paths:
  /users:
    get:
      summary: 사용자 목록 조회
      description: 페이지네이션된 사용자 목록을 반환합니다
      tags: [사용자]
      parameters:
        - name: page
          in: query
          description: 페이지 번호 (1부터 시작)
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: limit
          in: query
          description: 페이지당 항목 수
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
      responses:
        '200':
          description: 성공적인 응답
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/User'
                  pagination:
                    $ref: '#/components/schemas/Pagination'
              example:
                data:
                  - id: 1
                    username: "user1"
                    email: "user1@example.com"
                    fullName: "사용자 일"
                    createdAt: "2023-01-01T00:00:00Z"
                  - id: 2
                    username: "user2"
                    email: "user2@example.com"
                    fullName: "사용자 이"
                    createdAt: "2023-01-02T00:00:00Z"
                pagination:
                  total: 42
                  pages: 3
                  page: 1
                  limit: 20
        '401':
          $ref: '#/components/responses/Unauthorized'
      security:
        - bearerAuth: []

    post:
      summary: 새 사용자 생성
      description: 새로운 사용자 계정을 생성합니다
      tags: [사용자]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserCreate'
            example:
              username: "newuser"
              email: "newuser@example.com"
              password: "securePassword123"
              fullName: "신규 사용자"
      responses:
        '201':
          description: 사용자 생성됨
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '400':
          $ref: '#/components/responses/BadRequest'
        '409':
          description: 중복된 사용자명 또는 이메일
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                code: 409
                message: "이미 사용 중인 사용자명입니다"
      security:
        - bearerAuth: []

  /users/{userId}:
    parameters:
      - name: userId
        in: path
        required: true
        description: 사용자 ID
        schema:
          type: integer
          format: int64
    
    get:
      summary: 단일 사용자 조회
      description: ID로 사용자 정보를 조회합니다
      tags: [사용자]
      responses:
        '200':
          description: 성공적인 응답
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '404':
          $ref: '#/components/responses/NotFound'
      security:
        - bearerAuth: []
    
    put:
      summary: 사용자 정보 업데이트
      description: 기존 사용자의 정보를 업데이트합니다
      tags: [사용자]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserUpdate'
      responses:
        '200':
          description: 사용자 업데이트됨
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
      security:
        - bearerAuth: []
    
    delete:
      summary: 사용자 삭제
      description: ID로 사용자를 삭제합니다
      tags: [사용자]
      responses:
        '204':
          description: 사용자 삭제됨
        '404':
          $ref: '#/components/responses/NotFound'
      security:
        - bearerAuth: []

  /auth/login:
    post:
      summary: 사용자 로그인
      description: 사용자명과 비밀번호로 로그인하고 JWT 토큰을 받습니다
      tags: [인증]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - username
                - password
              properties:
                username:
                  type: string
                password:
                  type: string
                  format: password
            example:
              username: "testuser"
              password: "password123"
      responses:
        '200':
          description: 로그인 성공
          content:
            application/json:
              schema:
                type: object
                properties:
                  token:
                    type: string
                  user:
                    $ref: '#/components/schemas/User'
              example:
                token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
                user:
                  id: 1
                  username: "testuser"
                  email: "test@example.com"
                  fullName: "테스트 사용자"
                  createdAt: "2023-01-01T00:00:00Z"
        '401':
          description: 로그인 실패
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                code: 401
                message: "잘못된 사용자명 또는 비밀번호"

components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: integer
          format: int64
          description: 사용자의 고유 식별자
        username:
          type: string
          description: 사용자의 로그인 이름
        email:
          type: string
          format: email
          description: 사용자의 이메일 주소
        fullName:
          type: string
          description: 사용자의 전체 이름
        createdAt:
          type: string
          format: date-time
          description: 계정 생성 시간
      required:
        - id
        - username
        - email
        - createdAt
    
    UserCreate:
      type: object
      properties:
        username:
          type: string
          minLength: 3
          maxLength: 50
        email:
          type: string
          format: email
        password:
          type: string
          format: password
          minLength: 8
        fullName:
          type: string
      required:
        - username
        - email
        - password
    
    UserUpdate:
      type: object
      properties:
        email:
          type: string
          format: email
        fullName:
          type: string
        password:
          type: string
          format: password
          minLength: 8
    
    Pagination:
      type: object
      properties:
        total:
          type: integer
          description: 총 항목 수
        pages:
          type: integer
          description: 총 페이지 수
        page:
          type: integer
          description: 현재 페이지 번호
        limit:
          type: integer
          description: 페이지당 항목 수
    
    Error:
      type: object
      properties:
        code:
          type: integer
          description: HTTP 상태 코드
        message:
          type: string
          description: 오류 메시지
      required:
        - code
        - message
  
  responses:
    BadRequest:
      description: 잘못된 요청
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: 400
            message: "유효하지 않은 요청 데이터"
    
    Unauthorized:
      description: 인증 실패
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: 401
            message: "인증 필요"
    
    NotFound:
      description: 리소스를 찾을 수 없음
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: 404
            message: "요청한 리소스를 찾을 수 없습니다"
  
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT 인증 토큰

security:
  - bearerAuth: []

발전 방향 및 미래 전망

현재 동향

  1. 비동기 API 지원: WebSocket, Server-Sent Events 등 비동기 API에 대한 지원 향상
  2. 그래프QL 통합: REST API와 GraphQL의 통합 또는 상호 운용성
  3. 보안 강화: 제로 트러스트, 세밀한 접근 제어 및 보안 모델의 발전

앞으로의 과제

  1. 복잡한 API 시나리오: 마이크로서비스, 이벤트 기반 아키텍처 등 복잡한 API 아키텍처 지원
  2. API 거버넌스: 대규모 API 생태계에서의 거버넌스 및 관리
  3. API 진화: API 버전 관리 및 변경 관리 개선

미래 방향

  1. AI 통합: AI 기반 API 개발 및 관리 도구
  2. 자동화 향상: API 설계, 테스트, 배포의 완전 자동화
  3. 표준화 확대: 더 많은 산업 분야에서의 API 표준화

용어 정리

용어설명

참고 및 출처