Search

OpenAPI Spec 문서 간단한 작성 방법

카테고리
Back-end
태그
etc
Tech
게시일
2024/04/09
수정일
2024/04/19 04:06
시리즈
Design
1 more property

OpenAPI 3.0

OpenAPI 문서를 작성하는 방법은 Yaml 형식과 Json 형식이 있으며, 문법 또한 정해져 있습니다. 먼저, OpenAPI 3.0에 대해 IBM 문서를 참조하면 다음과 같습니다.
OpenAPI 3.0REST 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에 공유해두었습니다.