본문 바로가기
프로그래밍/기타

Open API Spefication 활용하기 - 2편 ( yaml 파일 분석하기 )

by 사바라다 2022. 9. 9.

안녕하세요. 오늘은 Open API Specification 2편입니다. 이전시간에 yaml 파일과 json 파일을 샘플로 확인했었습니다.

오늘은 해당 샘플 파일을 뜯어보면서 Open API Spefication의 구성요소들에 대해서 알아보는 시간을 가져보도록 하겠습니다.

샘플

아래는 이전 시간에 확인했던 Open API Specification의 전체 yaml 파일입니다. 파일을 보면 위에서부터 버전, 정보, 그리고 server의 주소 및 각 path에 대한 정보가 담겨져있습니다.

더보기
openapi: 3.0.1
info:
  title: OpenAPI definition
  version: v0
servers:
- url: http://localhost:8080
  description: Generated server url
paths:
  /api/open/:
    get:
      tags:
      - open-api-controller
      operationId: findResponses
      responses:
        "200":
          description: OK
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/OpenApiResponse'
    put:
      tags:
      - open-api-controller
      operationId: createBook
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OpenApiRequest'
        required: true
      responses:
        "200":
          description: OK
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/OpenApiResponse'
  /api/open/{id}:
    get:
      tags:
      - open-api-controller
      operationId: findById
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
          format: int64
      responses:
        "200":
          description: OK
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/OpenApiResponse'
components:
  schemas:
    OpenApiRequest:
      type: object
      properties:
        string:
          type: string
        number:
          type: integer
          format: int32
        number2:
          type: integer
          format: int64
        number3:
          type: number
          format: double
        time:
          type: string
          format: date-time
    OpenApiResponse:
      type: object
      properties:
        string:
          type: string
        number:
          type: integer
          format: int32
        number2:
          type: integer
          format: int64
        number3:
          type: number
          format: double
        time:
          type: string
          format: date-time

Version

openapi: 3.0.1

가장먼저 확인할 수 있는 정보는 version 정보입니다. Open Api Specification(이하 OAS)의 버전 정보는 openapi: major.minor.patch 형식을 따릅니다. 그리고 yaml 파일의 가장 위쪽에 기술해주시면 됩니다. major와 minor는 OAS의 메인 버전을 뜻합니다. 그리고 patch는 error로 인해서 버전업을 한 경우라고 기술되어있습니다. 이러한 버전 정보는 OAS에서 필수적으로 넣어주어야 하는 값 중 하나입니다. 이 값은 info.version 정보와는 다릅니다.

Info

info:
  title: OpenAPI definition
  version: v0

다음으로 필수적으로 기술되어야할 내용은 info에 대한 내용입니다. info는 API에 대한 metadata 정보를 기술합니다. info 내부에는 다양한 metadata가 존재하는데요. 그 내용은 아래와 같습니다.

  • title : API 제목 ( 필수 )
  • summary : API 간단 요약
  • description : API 설명 ( markdown 형식으로 설명 가능 )
  • termOfService : 이용 약관
  • contact : 관리자 정보
  • license : 라이센스 정보
  • version : API 버전 정보 ( 필수 )

Server

servers:
- url: http://localhost:8080
  description: Generated server url

target 되는 host server의 주소를 기록해두는 필드입니다. Optional한 필드이며 없을 경우 url 값은 기본으로 /를 가르키게 됩니다. 또한 해당 값은 1개의 값만 입력할 수 있는것이 아닌 Array로써 여러개의 값을 입력할 수 있습니다.

paths

paths:
  /api/open/:
    get:
      tags:
      - open-api-controller
      operationId: findResponses
  /api/open/{id}:
    get:
      tags:
      - open-api-controller
      operationId: findById
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
          format: int64

실제 API의 Operation들을 기술하는 것은 path에서 이루어 집니다. 가장 먼저 paths를 기술하고 실제 url을 입력합니다. 위의 예제에서는 아래처럼 /api/open/api/open/{id} 2가지 API를 기술하고 있습니다. 각 API의 path를 입력하고 그 아래에는 해당 API의 http Method를 기술합니다. 예제에서는 get 만을 사용했지만, put, post, delete, options, head, patch 등 일반적으로 사용하는 모든 http Method를 모두 사용할 수 있습니다.

/api/open/:
  get:
/api/open/{id}:
  get:

그리고 각각 API에 대한 세부적인 내용을 정의하고 있습니다. 각각 알아보도록 하겠습니다.

위의 예제의 가장 먼저 사용된 것은 tags 입니다. tags는 API operation의 논리적인 그룹을 위해서 사용할 수 있는 resource 입니다. 활용했을 때 같은 tag를 가지게 함으로써 함께 관리할 수 있게 되는 등의 장점이 있습니다. 그리고 그 아래 operationId를 기술하고 있습니다. 이는 API Operation이 가지는 unique string 값으로 id의 역할을 합니다. 해당 값은 모든 API들과는 구분될 수 있도록 값을 지정해야합니다. 해당값은 code-generate 했을 때 API의 method 이름으로 사용됩니다.

그 외에도 operation을 간단히 설명하는 summary와 디테일하게 설명하는 description을 간단한 파라미터로 가질 수 있습니다.

Parameters

Parameters 필드는 Operation의 path에 대한 추가적인 정보를 기술합니다. 추가적인 정보로는 /api/open/{id} 의 {id}에 들어가는 path, path의 가장 마지막에 별도 ?foo={bar} 의 형태로 들어가는 query, 그리고 header와 cookie를 종류로써 가집니다.

GET /api/open/{id}?foo={bar}

X-SABARADA: hello-cookie

위와 같은 예제를 만든다고 한다면 아래와 같이 yaml 파일을 작성할 수 있습니다.

parameters:
- name: id
  in: path
  required: true
  schema:
    type: integer
    format: int64
- name: foo
  in: query
  required: true
  schema:
    type: string
- name: X-SABARADA
  in: header
  required: true
  schema:
    type: string

RequestBody & ResponseBody

requestBody:
  content:
    application/json:
      schema:
        $ref: '#/components/schemas/OpenApiRequest'
  required: true
responses:
  "200":
      description: OK
      content:
      '*/*':
          schema:
          type: array
          items:
              $ref: '#/components/schemas/OpenApiResponse'

위에서 추가 Parameter에 대해서 알아보았습니다. 이번에는 HTTP body에 데이터를 실어 보내고 받아오는 RequestBody와 ResponseBody에 대해서 알아보도록 하겠습니다. requestBody와 responseBody 모두 content를 필수적인 필드로 가집니다. 그리고 이 content에는 Media Type을 기술 하고 그 schema를 기술하도록 되어있습니다.

일반적으로 schema는 complexity 형식이 많기 때문에 $ref 를 이용하여 components의 값을 참조하도록 합니다. response에는 request와 다르게 http status를 함께 포함시킵니다.

Components

OAS에는 다양하게 재활용 될 수 있는 object 들이 많이 있습니다. 예를 들어 Parameters, RequestBody, ResonseBody에 들어갈 수 있는 값들이 그러합니다. 이러하게 재사용될 수 있는 object 값들을 모아둔 곳이 components입니다. components에는 schemas, parameters, responses, headers 등을 기술 할 수 있습니다. 그리고 그 사용법은 위에서 잠깐 보았듯이 $ref를 이용하며 '#/components/schemas/OpenApiRequest'의 형식으로 사용합니다.

components:
  schemas:
    GeneralError:
      type: object
      properties:
        code:
          type: integer
          format: int32
        message:
          type: string
  parameters:
    skipParam:
      name: skip
      in: query
      description: number of items to skip
      required: true
      schema:
        type: integer
        format: int32
    limitParam:
      name: limit
      in: query
      description: max records to return
      required: true
      schema:
        type: integer
        format: int32
  responses:
    NotFound:
      description: Entity not found.
    IllegalInput:
      description: Illegal input for operation.
    GeneralError:
      description: General Error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/GeneralError'
  securitySchemes:
    api_key:
      type: apiKey
      name: api_key
      in: header
    petstore_auth:
      type: oauth2
      flows: 
        implicit:
          authorizationUrl: https://example.org/api/oauth/dialog
          scopes:
            write:pets: modify pets in your account
            read:pets: read your pets

각 Component는 보통 object 타입을 가지고 있습니다. 그리고 첫번째 값을 보면 properties를 가지고 그 안에 code와 message를 내부 값으로 가지고 있는 것을 알 수 있습니다. 이렇게 선언하면 json 형식이라면 아래와 같은 형식을 가지게 됩니다.

{
  "code" : 123, // integer, int32 형태
  "message" : "string"
}

마무리

오늘은 이렇게 Open API Specification 2편으로 실제로 Open API Specification 파일의 구성요소에 대해서 하나씩 알아보는 시간을 가져보았습니다.

다음시간에는 Spring Boot Server의 코드를 자동으로 Open API Specification 파일로 변화하는 방법에 대해서 알아보도록 하겠습니다.

감사합니다.

참조

[1] https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md

댓글