API 문서화로 코드 불일치 발견
목차
API 문서 작업을 했다. SQL, Java, SCSS 각각에 지침서를 추가하는 작업이었는데, 막상 쓰다 보니 예상보다 시간이 더 걸렸다. 단순히 있는 것을 정리하는 게 아니라, 코드와 실제 동작을 맞춰가며 검증해야 했기 때문이다.
문서화를 미루는 이유는 보통 "지금 당장 동작하는 게 더 급하다"는 논리다. 틀린 말은 아닌데, 그 판단이 쌓이면 나중에 아무도 건드리기 싫은 레거시가 된다. 그 레거시를 뜯어고칠 때 가장 먼저 드는 생각이 "이걸 왜 이렇게 만들었지?"인데, 대부분 답이 없다. 커밋 메시지는 "fix bug", PR 설명은 공란. 그러면 겁부터 나서 건드리기가 더 싫어진다.
문서화하면서 코드를 다시 봤을 때
이번에 API 엔드포인트 커버리지 전체, 요청/응답 예시, 오류 코드 정의까지 총 5개 파일을 손댔다.
| 문서 항목 | 상태 |
|---|---|
| 엔드포인트 커버리지 | 전체 |
| 요청/응답 예시 | 추가 |
| 오류 코드 정의 | 완료 |
| 수정 파일 | 5개 |
문서를 쓰다 보면 반드시 발생하는 일이 있다. 코드와 실제 동작이 다른 부분이 걸린다는 거다. 이번에도 몇 군데 발견했다. 스펙에는 400을 반환하는 걸로 적혀 있는데 실제로는 500을 뱉는다거나, 파라미터 타입이 string이어야 하는데 정수를 그냥 통과시키는 케이스. 직접 손으로 확인하지 않으면 좀처럼 잡기 어려운 불일치들이다. 같이 수정했다.
기본 스펙 포맷은 아래 형식으로 정리해뒀다.
## GET /api/v1/users/{id}
### Request
- id (required): 사용자 식별자
### Response (200 OK)
{ "id": 1, "name": "홍길동", "status": "ACTIVE" }
### Errors
- 400: 파라미터 오류
- 401: 인증 필요
- 404: 리소스 없음
이 형식 자체가 하나의 기준이 된다. 팀에서 새 엔드포인트를 추가할 때 "이 형식 맞춰서 써줘"라고 하면 일관성이 생기고, 나중에 OpenAPI 같은 자동화 도구로 연결하기도 훨씬 수월해진다.
SQL, Java, SCSS 지침서를 도메인별로 분리한 이유도 비슷하다. 각 레이어에서 신경 써야 할 포인트가 다르기 때문이다.
- SQL: 인덱스 유무, 조인 방향, N+1 가능성 같은 성능 관점
- Java: 예외 처리 전략, null 처리 컨벤션, 레이어 간 책임 분리
- SCSS: 네이밍 규칙, 변수 스코프, 컴포넌트 단위 모듈화
한 문서에 다 욱여넣으면 뭘 찾으러 왔다가 다른 것까지 읽게 되고, 결국 아무도 안 읽는다. 짧더라도 찾기 쉬운 편이 낫다.
코드에 "왜"가 없으면 생기는 일
코드를 짤 때 '나는 알고 있으니까 괜찮다'는 생각을 많이 한다. 그게 당장은 맞는 말이기도 하다. 문제는 6개월 뒤다. 같은 코드를 봤을 때 낯설어지는 경험, 개발하다 보면 한 번씩 겪게 된다.
"무엇"은 코드를 보면 안다. if (status == "ACTIVE")라고 쓰여 있으면 ACTIVE 상태를 체크한다는 건 읽힌다. 그런데 왜 INACTIVE가 아니라 ACTIVE만 허용하는가, 왜 이 시점에 체크하는가, 예외 케이스는 어떤 결정을 내렸는가 - 이건 코드만으로는 안 나온다. 그걸 나중에 다른 사람이, 혹은 미래의 내가 바꾸려고 하면 잘못된 방향으로 가기 딱 좋다. 맥락 없이 코드만 보면 "이상하다"고 느끼고, 그냥 고쳐버린다. 그게 사이드 이펙트의 시작이다.
ADR(Architecture Decision Record)이라는 관행이 있다. 왜 이 기술 스택을 선택했는지, 왜 이 구조로 설계했는지를 짧게라도 남기는 거다. API 수준에서도 같은 원칙이 적용된다. 설계 결정은 그 결정을 내린 맥락과 함께 있어야 의미가 있다.
실무에서 모든 API에 ADR 수준의 문서를 쓰는 건 오버킬이다. 하지만 최소한 이런 건 남겨야 한다.
- 이 엔드포인트가 왜 필요한가, 어떤 맥락에서 만들어졌는가
- 이 에러 코드를 이렇게 나눈 이유
- 향후 변경 시 주의해야 할 제약 조건이나 의존 관계
한 줄짜리 주석이라도 있으면 없는 것보다 훨씬 낫다. "이 필드는 레거시 호환을 위해 남겨둔 것, 신규 로직에서 참조하지 말 것" 같은 한 문장이 나중에 몇 시간을 아껴준다.
이번 작업에서 실질적으로 얻은 건 하나다. 문서화는 코드 품질을 점검하는 가장 저비용 방법 중 하나라는 것. 남에게 설명하려고 정리하다 보면, 막연하게 알고 있던 것과 실제로 아는 것 사이의 틈이 드러난다. 그 틈에서 버그가 나온다. 앞으로 새 API나 복잡한 로직을 만들 때는 구현과 문서를 함께 가져가는 흐름을 유지하려고 한다. 몰아서 나중에 쓰면 이미 기억이 휘발된 뒤다.
댓글 0
첫 댓글 달아줘.