📕 목차
1. As-is
2. To-be
1. As-is
📌 기존 방식의 문제점
React를 사용하던 프론트와 협업할 때는 어차피 컴포넌트 별로 api를 호출할 테니, api도 프론트 측에서 요청하는 대로 세분화하여 설계했었다.
그런데, 앱 개발자와 협업하는데 리액트처럼 컴포넌트 개념을 적용할 수 없었다.
즉 하나의 View에 대한 모든 데이터를 넘겨줘야 하는데 문제점이 너무 많았다.
예를 들어, 하나의 View를 구성하기 위해 총 4개의 도메인 A, B, C, D에 대한 정보가 필요하다고 가정해보자.
📌 Client 시점
- 한 번의 요청으로 모든 데이터를 받을 수 있으니 좋다.
- 응답 데이터가 너무 커질 수 있어서 네트워크 관점에서 느릴 수도 있다.
- 응답을 받을 때까지 Client는 다음 동작을 수행할 수 없게 된다.
📌 Server 시점
- api가 View에 종속적으로 묶여버려서 유연성이 급격하게 저하된다. (페이지 별로 api 열어줘야 함)
- 내부 로직이 복잡해져서 속도가 지연되거나, 최악의 경우 서버가 죽을 수도 있다.
- throughput, response time 모두 증가한다.
- 응답 포맷을 표준화할 수 없기에 복잡해진다.
- 나는 Dto를 JSend 프로토콜에 맞게 파싱해주는 유틸을 만들고 있다.
- 문제는 data로 넘어올 경우의 수가 너무 많아서, 모든 경우에 대응할 수 없다.
- 어떻게 만들었다 하더라도, 그럼 해당 유틸을 사용하기 위해서 Dto의 포맷이 제한되는 역효과가 벌어지는데 이로 인한 side effect를 예측할 수 없다.
- 성능 향상을 위해 Query문을 직접 작성하게 될 확률이 높으니, DBMS 종속성이 올라갈 확률도 높다.
📌 DB 시점
- JOIN해야 하는 테이블 수가 많아지므로 성능이 급격하게 떨어진다.
- 하나의 요청이 너무 복잡한 로직을 수행하는 경우, DB Lock에 걸려서 서비스 전체 품질이 저하될 수 있다.
2. To-be
📌 원칙을 적용하자!
그러다 문득 든 생각이 '그냥 4개의 도메인에 대해 4개의 API를 개방하고, 프론트가 비동기로 호출하면 되지 않아?'라고 떠올렸다.
React 애플리케이션을 생각해보자.
워낙 빈번하게 API를 호출하다 보니, 자르고 잘라서 가장 작은 단위의 api를 설계하려고 고심하지 않았던가.
비록 모바일 앱은 컴포넌트 별로 호출하지 못 한다고 해도, 위의 방식을 취했을 때의 장점은 분명히 존재하지 않을까?
📌 Client 시점
- 하나의 View를 구성하기 위해, 여러 개의 비동기 호출을 시행해야 하는 번거로움이 있다.
- A에 대해 B가 종속적이라면, A의 응답이 돌아올 때까지 사실상 동기적인 수행이 되어 지연될 수 있다.
- 그럼 A를 더 잘게 쪼개서, 빠른 응답이 돌아오도록 만들면 되지 않을까?
- 하나하나의 응답 패킷 크기 자체는 작아지므로, 비동기로 수행하면 전체 응답 속도는 줄어들 수도 있다. (가능성의 이야기다)
- HTTP 특성 상, 불필요한 핸드 쉐이크 과정은 감수해야 한다.
- HTTP3를 사용하면 단점도 해결할 수 있지 않을까?
📌 Server 시점
- 각 API는 하나의 Domain에 대해서만 신경쓰면 되므로 로직이 단순해진다.
- 로직이 단순해지므로 클래스 구조도가 단순해지고, 유지·보수성이 높아진다. (단위 테스트 느낌을 적용해봤다.)
- api가 더 이상 페이지에 종속적이지 않고, Domain 단위로 나눌 수 있다.
- 몰랐는데 내가 이야기하는 걸 듣더니, 누가 나보고 DDD 공부하냐고 하셨다. 아직 공부 못 해봤다...
- 응답 포맷이 간결해지므로 표준화가 가능하며, 관련된 Util도 충분히 일반화하여 예측 범위 내에서 계산 가능하다.
- JPA에서 제공해주는 기본 Query 만으로도 충분히 해결될 가능성이 높아, DBMS 의존도를 낮출 수 있다.
📌 DB 시점
- Join 테이블 수가 압도적으로 감소한다.
사실 이게 더 나은 해법인지는 모르겠다.
실제로 성능 테스트를 해본 것도 아니고, 철저히 이론과 설계 중심의 접근법으로 나온 나만의 생각일 뿐이라
API 만들다가 너무 복잡해져서 연구한 내용을 간략하게나마 정리해 두려고 작성했다.