ADR-0005: OpenAPI 생성 타입을 상위 계층에 그대로 노출한다
상태
Accepted
날짜
2026-08-10
맥락
서버 응답 타입을 OpenAPI 명세에서 생성하기로 정한 뒤, 그 타입을 어느 계층까지 노출할지가 남았습니다.
전통적인 접근은 부패 방지 계층(ACL)을 두는 것입니다. 생성 타입을 shared/api 안에 가두고 모든 상위 계층은 화면 전용 모델만 보게 하면, 백엔드 변경이 매핑 함수에서 멈추고 화면 어휘를 독립적으로 유지할 수 있습니다.
문제는 유지 비용입니다. 자매 백엔드 문서의 제약 조건에 "기존 응답 필드 삭제보다 필드 추가 작업의 변경 비용이 훨씬 낮다" 고 기재되어 있습니다. 즉 백엔드가 필드를 자주 추가한다는 전제가 이미 문서화되어 있습니다.
이 전제 위에서 매핑 계층을 두면, 필드가 추가될 때마다 매핑 함수를 수정하게 됩니다. 그 수정은 값을 옮겨 담기만 할 뿐 판단을 담지 않습니다.
결정
생성 타입을 pages·features·entities에서 그대로 임포트해 사용합니다. 필드 대응만 하는 변환 계층을 두지 않습니다.
생성물은 shared/api/generated/에 두고 커밋에 포함하며, 직접 수정을 금지합니다. 강제 수단은 ESLint의 경로 제한 규칙입니다.
화면에서 필요한 파생 값은 계산이며 변환이 아닙니다. 해당 슬라이스의 model 세그먼트에 계산 함수를 둡니다. 원본 타입을 그대로 두고 값을 계산하는 것과, 타입 전체를 다른 모양으로 옮겨 담는 것을 구분합니다.
세부 규칙은 API 계약 소비가 원본입니다.
검토한 대안
부패 방지 계층 도입
| 구분 | 내용 |
|---|---|
| 장점 | 백엔드 변경이 매핑 함수에서 멈춥니다. 화면 코드가 서버 어휘에 오염되지 않습니다. 서버 구조와 화면 요구가 어긋날 때 흡수 지점이 있습니다 |
| 단점 | 필드 추가마다 매핑을 수정해야 하며, 그 수정에 판단이 없습니다. 타입을 사실상 두 벌 유지하게 됩니다 |
| 기각 사유 | 백엔드가 필드를 자주 추가한다는 전제가 이미 문서화되어 있습니다. 가장 빈번한 변경 유형에서 가장 큰 비용을 치르는 구조입니다 |
필요할 때만 선택적으로 변환
| 구분 | 내용 |
|---|---|
| 장점 | 대부분은 그대로 쓰고 어긋나는 곳만 흡수해 두 방식의 이점을 취합니다 |
| 단점 | "언제 변환하는가"라는 판정이 들어갑니다 |
| 기각 사유 | 1순위 품질 목표가 예측 가능성입니다. 판정이 들어가는 규칙은 사람과 실행마다 결과가 갈립니다. 판정 기준을 문서화해도 경계 사례가 남습니다 |
결과
매핑 코드가 존재하지 않으므로 유지 대상이 하나 줄어듭니다. 백엔드가 필드를 추가하면 타입 재생성만으로 사용할 수 있습니다.
"서버 타입을 그대로 쓴다"는 예외 없는 규칙이므로 배치 판정이 필요 없습니다.
감수하는 사항은 다음과 같습니다.
- 백엔드 리팩터링이 화면 코드까지 전파됩니다. 필드명 변경이나 구조 변경이 발생하면 사용처 전부를 수정합니다. 컴파일 오류로 드러나므로 누락되지는 않지만 작업량은 그대로 발생합니다.
- 서버 어휘로 된 타입명이 화면 코드에 드러납니다.
AssessmentResponse같은 이름이 컴포넌트 입력 타입에 그대로 나타납니다. - 서버 구조와 화면 요구가 크게 어긋날 때 흡수 지점이 없습니다. 이런 상황이 반복되면 서버 응답 구조 자체를 협의하는 것이 옳으며, 프론트엔드가 매핑으로 감추면 문제가 드러나지 않습니다.
마지막 항목은 대가인 동시에 의도된 효과이기도 합니다. 계약이 화면에 맞지 않으면 그 사실이 코드에 드러나는 편이 낫습니다.