트러블슈팅

기능 중심 API 설계의 한계와 도메인 중심으로의 개선 과정

sudaruuu 2026. 3. 30. 16:14

2026.03.27 - [커피 주문 결제 시스템] - 포인트 기반 커피 주문 결제 시스템 (API 명세서)

 

포인트 기반 커피 주문 결제 시스템 (API 명세서)

2026.03.27 - [Spring 2기 과제] - 포인트 기반 커피 주문 결제 시스템 (도메인 설계) 포인트 기반 커피 주문 결제 시스템 (도메인 설계)기확 관련 메모포인트 기반으로 커피 메뉴를 조회하고, 충전한 포

sudaruuu.tistory.com

 

문제 상황

프로젝트를 시작하면서 요구사항을 기반으로

도메인 규칙, API 명세서, ERD를 비교적 꼼꼼하게 설계했다.

 

특히 다음과 같은 흐름을 기준으로 시스템을 구성했다.

  • 메뉴 조회
  • 포인트 충전
  • 주문 생성 및 결제
  • 인기 메뉴 조회

또한 도메인도 명확하게 나누었다.

  • User
  • Menu
  • Order
  • OrderItem
  • Payment
  • PointHistory

처음에는 이 구조가 충분히 잘 나뉘어 있다고 생각했다.

 

하지만 실제 구현을 진행하면서
설계와 코드 사이에서 어색한 지점들이 하나씩 보이기 시작했다.


원인 분석

1. 기능 중심으로 나눈 API 구조

초기 API 명세서는 “무슨 기능이 필요한가”를 기준으로 작성되었다.

 

예를 들어:

  • 포인트 충전 → /api/points/charge
  • 결제 조회 → /api/payments/{orderId}
  • 주문 상품 조회 → /api/orders/{orderId}/items

이처럼 기능 단위로 나누는 것은 빠르게 설계하기에는 좋았지만,
문제는 도메인 책임과 정확히 일치하지 않는다는 점이었다.


2. 도메인 책임이 드러나지 않는 구조

구현을 하면서 가장 크게 느낀 생각한 것은

“이 기능을 누가 책임지는 게 맞지?” 이다.

 

예를 들어:

  • 포인트 충전은 point 기능일까, user 기능일까?
  • 주문과 결제는 정말 분리된 흐름일까?
  • order_item은 독립 도메인인가, order의 일부인가?

처음 설계에서는 각각 나누어 놓았지만,
실제 코드에서는 자연스럽게 하나로 묶이거나,
특정 도메인에 속하는 형태로 구현되고 있었다.


3. 내부 로직과 API의 경계가 모호함

초기에는 비즈니스 흐름을 기준으로 API를 나열하다 보니
도메인별 책임이 명확하게 드러나지 않는 구조였다.

구현을 진행하면서 이러한 방식이 어색하다는 것을 느꼈고,
API를 도메인 중심으로 다시 정리하게 되었다.

 

이를 개선하기 위해

User, Order, Menu와 같은 도메인을 기준으로 외부 API를 재정의하고,
각 도메인의 책임이 명확하게 드러나도록 재설계하였다.


해결 방법

설계를 다시 보면서 기준을 하나로 정리했다.

"기능이 아니라 도메인 책임 기준으로 나누자"


⭐ 변경 API 명세서

user
- GET  /api/users
- GET  /api/users/{userId}
- GET  /api/users/{userId}/point
- POST /api/users/{userId}/points/charge

menu
- GET /api/menus
- GET /api/menus/{menuId}
- GET /api/menus/popular

order
- POST /api/orders
- GET  /api/orders/{orderId}
- GET  /api/orders/{orderId}/items

payment
- GET /api/payments/{orderId}

pointhistory
- GET /api/points/history/{userId}

 

각 도메인별로 책임이 명확하도록 수정했고,

통일성 있게 바꿨다.


개선 결과

변경 이후 API는 다음과 같은 특징을 가지게 되었다.

  • 도메인 기준으로 일관된 구조
  • 책임이 명확한 API
  • 내부 로직과 외부 API 분리
  • 실제 코드 구조와 동일한 명세서

느낀 점

처음 설계는 틀린 것이 아니었다.

오히려 요구사항을 빠르게 정리하는 데에는 충분히 좋은 출발점이었다.
하지만 실제 코드를 구현하면서 API 명세서가 다소 부자연스럽게 느껴졌다.

 

이번 구현을 진행하면서 가장 크게 느낀 점은

⭐ 좋은 설계는 한 번에 완성되지 않는다는 것이다.

 

초기에 요구사항을 기준으로 빠르게 설계를 진행하고,
이후 구현을 통해 지속적으로 수정해 나가는 과정이 중요하다고 느꼈다.

 

또한,

  • API는 단순 기능 목록이 아니라 도메인의 책임을 표현해야 한다
  • 내부 로직과 외부 API는 반드시 구분해야 한다
  • 설계는 구현과 함께 계속 다듬어져야 한다

라는 점을 다시 한번 깨닫게 되었다 !!