표면 좁히기
개요
API surface가 넓을수록 자유도가 커지고, 자유도가 커질수록 우회 가능성도 커진다.
그래서 하네스 친화적 API는 가능하면 좁고 단순한 surface를 선호한다.
1. entry point가 많을수록 통제는 약해진다
같은 기능을 수행하는 entry point가 많으면, 정상 경로와 예외 경로의 차이가 흐려진다.
문제는 다음처럼 나타난다.
- 같은 동작을 facade, helper, util, raw service가 모두 제공한다
- 팀마다 다른 경로를 정상처럼 사용한다
- AI는 주변에서 가장 짧아 보이는 경로를 복제한다
entry point가 많다는 것은 유연성보다 통제 비용 증가에 더 가깝다.
2. surface는 넓음보다 계층이 문제다
공개 함수 수 자체보다 더 중요한 것은, 공개 surface가 어떤 계층을 노출하는가다.
위험한 surface:
- 내부 객체를 직접 반환한다
- 중간 계층 없이 deep dependency에 접근하게 한다
- 내부 상태 수정 권한을 넓게 노출한다
좋은 surface:
- 외부가 알아야 하는 계약만 노출한다
- 내부 구현 세부는 감춘다
- 호출자가 깊은 구조를 탐색하지 않아도 된다
3. 좁은 surface의 장점
- 무엇이 합법 경로인지 분명해진다
- lint, analyzer, type restriction을 붙이기 쉬워진다
- 문서와 코드가 같은 말을 하게 된다
- 리뷰 기준이 단순해진다
- AI가 잘못된 경로를 고를 확률이 줄어든다
좁은 surface는 단순히 깔끔해서 좋은 것이 아니라, 검사와 강제가 쉬워지기 때문에 좋다.
4. 너무 좁아도 생기는 문제
반대로 surface를 과도하게 줄이면, 호출자가 우회를 만들 수밖에 없는 상황이 생긴다.
예:
- 정상 API가 실제 사용 시나리오를 다 못 담는다
- 자주 필요한 변형을 전혀 표현하지 못한다
- 모든 작업이 boilerplate로 바뀐다
이 경우 사람도 AI도 결국 helper를 바깥에 새로 만든다. 중요한 것은 surface의 절대 크기가 아니라, 필요한 일을 공식 경로 안에서 끝낼 수 있느냐다.
5. surface를 좁힐 때 보는 기준
- 이 함수는 정말 외부에서 알아야 하는가
- 이 객체를 직접 노출하지 않아도 되는가
- 두 entry point가 사실상 같은 일을 하는가
- 내부 계층을 직접 만지지 않도록 한 단계 감쌀 수 있는가
- 지금 convenience가 사실상 두 번째 공식 API가 되고 있지 않은가
이 질문으로 surface를 정리하면, 합법 경로가 더 선명해진다.
6. 좋은 pattern
- facade 중심 진입
- command 중심 mutation
- read / write surface 분리
- scoped query object
- feature별 public API barrel 고정
핵심은 외부가 내부 그래프를 직접 탐색하지 않게 만드는 것이다.
요약
좁은 surface는 제약이 아니라 통제를 위한 설계다.
- entry point가 적고
- 노출 계층이 낮고
- 내부 구현 세부를 감추며
- 필요한 시나리오는 공식 경로 안에서 처리할 수 있어야 한다
좋은 API surface는 많은 기능을 보여주는 표면이 아니라, 정상 경로만 선명하게 남겨두는 표면이다.