OpenAPI 3.0
OpenAPI 문서를 작성하는 방법은 Yaml 형식과 Json 형식이 있으며, 문법 또한 정해져 있습니다. 먼저, OpenAPI 3.0에 대해 IBM 문서를 참조하면 다음과 같습니다.
OpenAPI 3.0 은 REST API를 정의하기 위한 개방형 스펙입니다.
OpenAPI 3.0 스펙 (OAS) 은 RESTful API에 대한 표준 언어에 구애받지 않는 인터페이스를 정의합니다. 이를 통해 사용자와 컴퓨터 모두 소스 코드, 문서 또는 네트워크 트래픽 검사를 통해 액세스하지 않고 서비스의 기능을 발견하고 이해할 수 있습니다. 적절하게 정의된 경우 사용자는 최소한의 구현 논리로 원격 서비스를 이해하고 상호작용할 수 있습니다.
그런 다음 문서 생성 도구에서 OpenAPI 3.0 정의를 사용하여 API, 다양한 프로그래밍 언어로 서버 및 클라이언트를 생성하는 코드 생성 도구, 테스트 도구 및 기타 여러 유스 케이스를 표시할 수 있습니다.
이러한 OpenAPI Specification 문서 작성 방법은 아래의 깃허브 링크를 참조하면 좋습니다. 다만, 이 글에서는 이 문서를 모두 읽지 않고 간단한 작성방법을 공유하고, 예제를 작성하여 Swagger를 생성하는 부분까지 간단한 실습을 해볼 수 있도록 해볼 예정입니다.
OpenAPI Specification
# 기본 영역
openapi: 3.0.0
servers:
- url: 'http://petstore.swagger.io/v2'
info:
... 생략
# tags 영역
tags:
- name: pet
description: Everything about your Pets
... 생략
# paths 영역 (endpoint uri)
paths:
/pet:
post:
... 생략
# components 영역 (스키마 영역)
components:
requestBodies:
... 생략
schemas:
... 생략
YAML
복사
기본적인 구조는 위의 yaml 파일 형태처럼 돼 있습니다. 각각의 요소를 설명드리면 다음과 같이 설명드릴 수 있을 것 같습니다.
Basic specs
openapi: 3.0.0
servers:
- url: 'https://api.0x10.kr/api/v1'
info:
title: 어드민 로그인 API 스펙
description: >-
어드민 로그인을 위해 필요한 계정 정보를 조회하는 API 입니다.
API 접근 권한은 STAFF 이상이어야 합니다.
version: 1.0.0
tags:
- name: admin-user
description: 어드민 데이터베이스 내에 있는 계정 및 정보에 대한 태그입니다.
YAML
복사
openapi
•
버전을 나타내며, 위 샘플 기준으로 3.0.0임을 알 수 있습니다.
servers
•
openapi로 API 요청을 날리는 서버의 URL 경로를 지정합니다. 예를 들면 https://api.0x10.kr/api/v1 이렇게 설정해두면, paths에서 /users 요청의 경우 https://api.0x10.kr/api/v1/users 로 요청을 날리게 됩니다.
info
openapi의 정보를 작성하는 영역입니다. 해당 영역에서는 title, description, version, license 등을 기록할 수 있습니다.
•
title
OpenAPI 문서의 제목을 작성합니다.
•
description
OpenAPI 문서에 대한 구체적인 설명을 작성합니다. 엔터 문자가 들어가도 가능합니다.
•
version
API 스펙의 버전을 나타냅니다. openapi의 문서 작성 방법의 버전과는 다르게, 자체적인 API 버저닝을 작성하는 영역입니다.
•
license
현재 스펙의 라이센스 정보를 나타냅니다.
Tags
tags 는 작성하는 API의 그룹을 지정해줄 수 있도록 합니다. 예를 들면 아래와 같이 users, users/{id} 와 같은 path의 API가 있는데, 이는 user라는 항목에 포함돼 있으니, Swagger에 그룹으로 묶을 수 있으면 좋겠지요. 따라서 tag에 user라는 그룹을 만들어 묶어줄 수 있습니다.
Paths
paths는 우리가 제공할 API의 스펙 URI를 작성할 수 있습니다. 기본 구조는 아래와 같습니다.
paths:
/users:
get:
tags:
- user
summary: 이용자 계정 목록을 가져옵니다.
description : 이용자 계정 목록을 가져오며, 조회를 위해서는 로그인이 필요합니다.
parameters:
...
post:
tags:
- user
summary: 이용자 계정을 생성합니다.
description : 이용자 계정을 생성합니다. 계정 생성 시 비밀번호 입력 확인의 경우 프론트에서 검증합니다.
requestBody:
YAML
복사
servers 에 작성된 URL 뒤에 path를 붙인다, 라고 이해하면 빠를 것 같습니다. path를 지정해주고, 원하는 HTTP Method를 지정해줍니다. 그리고, tags와 기타 설명, parameters 혹은 requestBodies 등을 설정해주고, 이에 대한 응답 예시를 설정해주어야 합니다.
get
get 메소드에서는 parameter를 설정해줄 수 있습니다. parameter에는 header, path, query 등이 있을 수 있습니다. 이에 대한 예제와 설명은 다음과 같습니다.
summary
•
URI의 제목(간단한 설명)을 작성할 수 있습니다.
description
•
URI에 대한 상세한 설명을 작성할 수 있습니다.
parameters
•
parameters : 파라미터 영역을 나타내며, 각 속성들을 나열하여 정의합니다.
•
name : 파라미터의 이름입니다.
•
in : 파라미터가 어떤 형태로 작성되는지 정의하는 영역입니다. query, header, path 등을 입력합니다.
•
description : 파라미터의 값을 설명합니다.
•
rquired : 필수 여부를 판단하며 true / false로 정의할 수 있습니다.
•
schema : 파라미터가 가질 수 있는 데이터 값을 지정합니다.
◦
type : 어떤 스키마 타입인지 정의합니다.
▪
array : 배열
▪
object : 오브젝트 (데이터 묶음)
▪
boolean : 불리언 타입(참/거짓)
▪
integer : 숫자
▪
string 문자열
◦
enum : 스키마 값의 선택지를 정의할 수 있습니다.
◦
example : 에제 값을 정의할 수 있습니다.
◦
items : 만약 type을 array로 설정하였다면, 배열 내의 데이터 타입을 구체적으로 지정할 수 있습니다.
paths:
/users/{userId}/cards:
get:
tags:
- users
summary: 이용자가 발급한 카드 목록 조회
description : 이용자 계정에 해당하는 발급된 카드 목록을 가져옵니다.
parameters:
- name: userId
in: path # path parameter에 대한 정의
description: 조회하고자 하는 유저의 아이디값을 입력합니다.
required: true
schema:
type: integer
format: int32
minimum: 1
- name: status
in: query # query parameter에 대한 정의
style: form
description: 조회하고자 하는 카드의 상태를 입력합니다.
schema:
type: boolean
example: true
enum:
- true
- false
responses:
'200':
description: Pagination 된 유저 정보 응답값
content:
application/json:
schema:
# Response 값 형태를 정의한 component입니다.
# 이에 대한 설명은 아래에서 설명하도록 하겠습니다.
$ref: "#components/schemas/UserCards"
YAML
복사
Example Parameters
Example Responses
post
post 메소드 역시 get 메소드와 비슷하지만 여기서는 요청할 때 body를 선언해주어야 합니다.
requestBody
•
요청 데이터의 형태를 정의할 수 있습니다.
•
이런 정보의 경우 components에서 정의해두고 $ref(레퍼런스, referense) 형태로 가져와 사용할 수 있습니다.
paths:
/users:
post:
tags:
- users
summary: 이용자 계정 생성
description : 이용자 계정을 생성합니다. 계정 생성 시 비밀번호 입력 확인의 경우 프론트에서 검증합니다.
requestBody:
$ref: "#components/requestBodies/User"
responses:
'200':
description: 생성된 유저의 최소 데이터를 반환합니다.
content:
application/json:
schema:
$ref: "#components/schemas/User"
'400':
description: 값을 잘못 입력할 경우 에러를 반환합니다.
content:
application/json:
schema:
$ref: "#components/schemas/Error"
type: object
'409':
description: 이미 유저 계정이 동일한 게 존재할 경우 에러를 반환합니다.
content:
application/json:
schema:
$ref: "#components/schemas/Error"
type: object
YAML
복사
Example request body
Example responses
responses
메소드와 관계 없이 어떤 응답값을 반환할지 정의할 수 있습니다. 반환 코드에 따라 어떤 정보를 반환할지, 어떤 형태로 반환할지 정의할 수 있습니다.
description
응답값에 대한 상세 설명을 작성할 수 있는 영역입니다.
responses
응답값을 정의하는 영역입니다.
•
‘200’ : 반환하고자 하는 데이터가 어떤 Status일 때 해당하는지 정의합니다. 이는 http response status가 200 OK일 때를 의미하며, status 코드와 일치하게 정의할 수 있습니다.
•
content : 반환하고자 하는 데이터를 정의하는 영역입니다.
◦
application/json : response 데이터를 json 형태로 반환할 때 정의합니다.
◦
schema : 반환할 데이터의 형태를 구체적으로 정의할 수 있습니다.
▪
$ref : 스펙 내부에 응답값의 스키마를 참조하는 경로를 지정합니다.
Components
요청값 혹은 응답값의 형태를 정의할 수 있는 영역입니다. 여기서는 requestBodies, schema와 같이 데이터를 정의하여 $ref 형태로 참조가 가능하게끔 활용할 수 있습니다.
requestBodies
정의하고자 하는 요청값을 상세히 정의할 수 있습니다. 상세 예제는 다음과 같습니다.
components:
requestBodies:
User:
content:
application/json:
schema:
type: object
required:
- email
- password
- birthDate
- gender
- phoneNumber
properties:
email:
type: string
example: kkamikoon@gmail.com
description: 아이디로 사용할 Email을 입력합니다.
password:
type: string
example: testtest
description: 비밀번호를 입력합니다.
birthDate:
type: string
example: 19940101
description: 태어난 생년월일을 기입하며 형태는 `YYYYMMDD` 입니다.
gender:
type: string
example: 'female'
description: 성별을 나타내는 문자열이 들어갑니다. (male/female)
phoneNumber:
type: string
example: "01012341234"
YAML
복사
schema
정의하고자 하는 응답값을 상세히 정의할 수 있습니다. 상세 예제는 다음과 같습니다.
components:
schema:
CardDetail:
allOf:
- $ref: "#components/schemas/Card"
- type: object
properties:
alias:
type: string
description: 카드 별명
example: "황금별의 황금카드"
cardKey:
type: string
format: uuid
description: 카드를 특정할 수 있는 고유 아이디 값
example: ef4de7b28f214fcfac8ee5d1c8261b20
cardName:
type: string
description: 카드 이름
example: "KB국민카드"
Card:
type: object
properties:
id:
type: integer
description: 카드의 고유 아이디 값
status:
type: boolean
enum:
- true
- false
description: 카드 상태 (0 비활성, 1 활성 )
cardNumber:
type: string
description: 마스킹 된 카드 번호
example: "1234-****-****-*210"
createdAt:
type: string
format: date-time
description: 카드 정보가 생성된 날짜
updatedAt:
type: string
format: date-time
description: 카드 정보가 업데이트된 날짜
UserWithCard:
$ref: "#components/schemas/User"
type: object
properties:
card:
$ref: "#components/schemas/CardDetail"
description: 현재 활성화 돼 있는 카드 정보를 반환합니다. 만약 카드가 없을 경우 null 값이 반환됩니다.
type: object
User:
type: object
required:
- id
- nickname
- phoneNumber
- gender
- birthDate
- email
- isActive
- createdAt
- updatedAt
- lastAccessed
properties:
id:
type: integer
format: int64
example: 1
description: 유저의 고유 아이디
nickname:
type: string
description: 유저의 닉네임
example: 황금별
phoneNumber:
type: string
description: 휴대폰 번호
example: "01012341234"
gender:
type: string
description: 유저의 성별
enum:
- 'male'
- 'female'
birthDate:
type: string
example: 19940101
description: 태어난 생년월일을 기입하며 형태는 `YYYYMMDD`
email:
type: string
description: 유저의 이메일
example: kkamikoon@gmail.com
createdAt:
type: string
format: date-time
description: 유저 계정이 생성된 날짜
updatedAt:
type: string
format: date-time
description: 유저 계정이 업데이트된 날짜
lastAccessed:
type: string
format: date-time
description: 마지막 접속 날짜
Error:
type: object
required:
- code
- message
properties:
code:
type: string
description: 에러 코드
example: "ERROR-FOUND"
message:
type: string
description: 에러에 대한 상세 메시지
example: "에러메시지 입니다."
YAML
복사
CardDetail
UserWithCard response examples
Example
아래의 예제는 위의 설명드렸던 예제의 전체 코드는 Github에 공유해두었습니다.