[GPT Actions] 6. OpenAPI 스키마 고급 기능 및 베스트 프랙티스
- OpenAPI 스키마의 고급 기능과 API 설계 베스트 프랙티스에 대한 소개
- 태그, 확장 필드, 서버 변수, 요청/응답 예제, 복잡한 스키마 모델링 등의 개념 설명
- 일관된 명명 규칙, HATEOAS 원칙, 페이지네이션 구현 등 API 설계시 고려해야 할 중요 개념 다룸
안녕하세요! 이번 파트에서는 OpenAPI 스키마의 고급 기능들과 API 설계 시 고려해야 할 베스트 프랙티스에 대해 알아보겠습니다. 이를 통해 더 강력하고 유지보수가 쉬운 API를 설계할 수 있습니다.
태그(Tags) 사용하기
태그를 사용하면 API 엔드포인트를 논리적인 그룹으로 구성할 수 있습니다. 이는 큰 규모의 API에서 특히 유용합니다.
tags:
- name: books
description: Operations about books
- name: authors
description: Operations about authors
- name: reviews
description: Operations about book reviews
paths:
/books:
get:
tags:
- books
summary: List all books
# ... (나머지 부분은 그대로 둡니다)
확장 필드(Extension Fields) 사용하기
OpenAPI 스키마에서 'x-'로 시작하는 필드를 사용하여 사용자 정의 확장을 추가할 수 있습니다.
paths:
/books:
get:
summary: List all books
x-rate-limit: 100
x-requires-authorization: true
# ... (나머지 부분은 그대로 둡니다)
서버 변수(Server Variables) 사용하기
다양한 환경(개발, 스테이징, 프로덕션 등)에 대한 서버 URL을 정의할 수 있습니다.
servers:
- url: https://{environment}.example.com/v1
variables:
environment:
default: api
enum:
- api
- api.dev
- api.staging
요청/응답 예제 추가하기
여러 예제를 제공하여 API 사용자의 이해를 돕습니다.
paths:
/books:
post:
summary: Add a new book
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Book'
examples:
fiction:
summary: A fiction book
value:
title: "The Great Gatsby"
author:
name: "F. Scott Fitzgerald"
publicationYear: 1925
non-fiction:
summary: A non-fiction book
value:
title: "A Brief History of Time"
author:
name: "Stephen Hawking"
publicationYear: 1988
# ... (나머지 부분은 그대로 둡니다)
복잡한 스키마 모델링
때로는 더 복잡한 데이터 구조를 모델링해야 할 수 있습니다. OpenAPI는 이를 위한 다양한 기능을 제공합니다.
a) oneOf, anyOf, allOf 사용:
components:
schemas:
Pet:
type: object
discriminator:
propertyName: petType
properties:
name:
type: string
petType:
type: string
required:
- name
- petType
Cat:
allOf:
- $ref: '#/components/schemas/Pet'
- type: object
properties:
huntingSkill:
type: string
enum:
- clueless
- lazy
- adventurous
- aggressive
Dog:
allOf:
- $ref: '#/components/schemas/Pet'
- type: object
properties:
packSize:
type: integer
format: int32
minimum: 0
b) 추가 속성 허용:
components:
schemas:
ExtensibleBook:
type: object
properties:
title:
type: string
author:
type: string
additionalProperties: true
베스트 프랙티스
a) 일관된 명명 규칙 사용:
경로: 복수형 명사 사용 (/books, /authors)
파라미터: camelCase 사용
스키마: PascalCase 사용
b) HATEOAS (Hypermedia as the Engine of Application State) 원칙 적용:
응답에 관련 리소스 링크를 포함시킵니다.
components:
schemas:
BookWithLinks:
type: object
properties:
id:
type: integer
title:
type: string
links:
type: object
properties:
self:
type: string
format: uri
author:
type: string
format: uri
reviews:
type: string
format: uri
c) 페이지네이션 구현:
대량의 데이터를 반환하는 엔드포인트에 페이지네이션을 적용합니다.
paths:
/books:
get:
summary: List books
parameters:
- name: page
in: query
schema:
type: integer
default: 1
- name: limit
in: query
schema:
type: integer
default: 20
# ... (나머지 부분은 그대로 둡니다)
연습문제
이제 여러분 차례입니다! 다음 요구사항을 만족하도록 스키마를 수정해보세요:
'users' 태그를 추가하고, 새로운 '/users' 엔드포인트 생성 (GET, POST 메서드)
User 스키마 정의 (id, username, email, registrationDate)
'/users/{userId}/books' 엔드포인트 추가 (사용자가 빌린 책 목록 반환)
서버 변수를 사용하여 개발 및 프로덕션 환경 URL 정의
User 스키마에 HATEOAS 링크 추가
정답
여러분의 수정된 스키마가 다음과 비슷하다면 정답입니다:
openapi: 3.1.0
info:
title: Enhanced Bookstore API
version: 1.3.0
servers:
- url: https://{environment}.bookstore-api.example.com/v1
variables:
environment:
default: api
enum:
- api
- api.dev
tags:
- name: books
description: Operations about books
- name: authors
description: Operations about authors
- name: reviews
description: Operations about book reviews
- name: users
description: Operations about users
paths:
/users:
get:
tags:
- users
summary: List users
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
post:
tags:
- users
summary: Create a new user
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/NewUser'
responses:
'201':
description: User created
content:
application/json:
schema:
$ref: '#/components/schemas/User'
/users/{userId}/books:
get:
tags:
- users
- books
summary: Get books borrowed by a user
parameters:
- name: userId
in: path
required: true
schema:
type: integer
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Book'
components:
schemas:
NewUser:
type: object
properties:
username:
type: string
email:
type: string
format: email
required:
- username
- email
User:
allOf:
- $ref: '#/components/schemas/NewUser'
- type: object
properties:
id:
type: integer
registrationDate:
type: string
format: date-time
links:
type: object
properties:
self:
type: string
format: uri
borrowedBooks:
type: string
format: uri
# ... (기존의 Book, Author, Review 스키마는 그대로 유지)
마무리
축하합니다! 이번 파트에서는 OpenAPI 스키마의 고급 기능들과 API 설계의 베스트 프랙티스에 대해 알아보았습니다. 태그를 사용한 논리적 그룹화, 확장 필드를 통한 사용자 정의, 서버 변수를 이용한 다중 환경 지원, 복잡한 스키마 모델링 등을 배웠습니다.
또한 일관된 명명 규칙, HATEOAS 원칙, 페이지네이션 등 API 설계 시 고려해야 할 중요한 개념들도 다루었습니다.
이러한 고급 기능과 베스트 프랙티스를 적용하면, 더욱 강력하고 사용하기 쉬우며 확장 가능한 API를 설계할 수 있습니다. 실제 프로젝트에서 이러한 개념들을 적용해 보면서 더 깊이 있는 이해를 얻을 수 있을 것입니다.
OpenAPI 스키마 작성과 API 설계에 대해 더 궁금한 점이 있다면 언제든 물어보세요. 여러분의 API 개발 여정에 행운이 있기를 바랍니다!