🚀 94sssh
Published on

2026.01.24

[실전 API 설계] - 10. OpenAPI를 사용한 API 설계

10.1. 문제

10.1.1. 도메인 모델을 OpenAPI로 전환

일반적으로 OpenAPI 정의서의 스키마는 도메인 모델의 속성과 관계를 표현.
도메인 모델 관점에서는 '모델', '개념' 사용
데이터 구조 관점에서는 '스키마' 사용

10.1.2. 재사용성 보장

  • 인라인 스키마: 스키마를 연산의 한 부분으로 기술하는 것

10.2. 스키마 생성

10.2.2. 공통 스키마 참조

OpenAPI 정의서의 components에 공통 스키마를 생성하면 $ref를 사용해 스키마를 참조할 수 있음. $ref의 값은 JSON 포인터로, #으로 시작하고 /components/schemas/에 스키마 이름을 붙인 문자열.

필드는 소문자여야 하고, 공백이 없어야 하는 JSON 객체 명명 관습을 따르고, 각 필드에 type을 추가해야 함.

10.3. API 연산과 CRUD

  • 리소스: 도메인 모델에 있는 개념의 개별 인스턴스. 개별 리소스에 대한 경로 이름을 지정하는 좋은 방법은 모델의 복수형 이름 뒤에 고유 식별자를 추가하는 것 (ex: /users/123)

API 경로를 구분하는 방법

  • 리소스 엔드포인트: 개별 리소스를 가리키는 URL
  • 컬렉션 엔드포인트: 리소스의 목록을 가리키는 URL, 동일한 타입의 모든 리소스를 조회, 페이징, 필터 개념 사용

CRUD 연산에서 POST, GET은 모두 사용하지만, PUT, PATCH, DELETE는 리소스 엔드포인트만 사용

10.3.1. API 요청과 응답 정의

  • 리소스 배열을 응답 본문 최상위 레벨로 반환하지 않는 이유
    1. 응답 본문 최상위에 배열이 오면 오래된 브라우저는 CORS 제약을 우회할 수 있음
    2. 리소스 배열 외에 추가적인 메타데이터 정보를 반환해야 하는 상황이 있을 수 있음(페이징 조회 등)

컬렉션 엔드포인트는 비어있는 배열을 반환하더라도 상태 코드 200을 반환해야 함. 이는 컬렉션이 비어 있을 뿐 컬렉션 자체는 존재하기 때문

연산상태 코드응답 본문
생성201비어 있고 Location 헤더 반환
읽기200리소스 또는 컬렉션 객체
수정200리소스
삭제204비어 있음

일반적으로 CRUD 방식으로 API 설계 시, 서브리소스 경로 사용을 최소화하고, 가능한 짧은 경로를 사용하는 것이 바람직. 짧은 경로 사용 시 다른 행위와 충돌이 발생하는 경우에만 서브리소스 컬렉션 엔드포인트를 사용.
서브리소스 컬렉션 엔드포인트/{schemas}/{id}/{subSchemas}의 구조를 가짐.