일기 slecs

마이페이지 API 문서화로 엔드포인트 누락·불일치 수정

목차

마이페이지 관련 API를 문서화하다가 엔드포인트 누락과 스펙 불일치를 몇 군데 발견해서 같이 수정했다. 처음엔 문서 하나 추가하는 작업이었는데, 손을 대다 보니 실제 동작과 달랐던 부분이 보여서 수습까지 함께 하게 된 케이스다.

왜 지금 문서화였나

레거시 URL 리다이렉트 로직이 코드에는 있는데 아무데도 명세가 없었다. "이 엔드포인트 아직 살아있어?" 같은 질문이 오가던 상황. 신규 인원이 붙든, 반년 뒤의 내가 보든 코드 전체를 처음부터 뒤져야 하는 구조였음.

마이페이지 도메인은 사용자 식별자 기반으로 데이터를 조회하는 엔드포인트가 여러 개 묶여 있어서, 경로 규칙이 일관성 없이 흩어져 있으면 클라이언트 쪽에서 계속 혼선이 생긴다. 실제로 요청 파라미터 이름이 코드와 내부 메모가 달랐던 케이스도 있었음. 어디를 믿어야 하는지 모르는 상태에서 개발자가 코드를 들여다보고, 직접 찔러보고, 그제야 "아 이렇게 쓰면 되는구나"를 파악하는 흐름이 반복되고 있었다.

코드가 아무리 깔끔하게 짜여 있어도 문서가 없으면 다른 사람이, 또는 미래의 내가 쓰기 어렵다. 이게 문서화를 미루면 안 되는 이유의 전부라고 생각함.

실제로 담은 내용

엔드포인트 명세는 경로, HTTP 메서드, 요청/응답 스펙 순으로 정리했다. 파라미터는 필수/선택 구분과 타입, 유효성 규칙까지 담았고, 오류 코드는 상황별로 분리해서 "왜 이 에러가 나는지"까지 설명을 붙였음.

## GET /api/v1/users/{id}/mypage

### Request Parameters
- id (required, integer): 사용자 식별자
- include_deleted (optional, boolean): 탈퇴 처리된 계정 포함 여부. 기본값 false

### Response (200 OK)
{
  "id": 1,
  "name": "홍길동",
  "status": "ACTIVE",
  "profile": { ... }
}

### Errors
- 400: 파라미터 타입 불일치 (id가 정수가 아닌 경우)
- 401: 인증 토큰 없음 또는 만료
- 403: 본인 외 타인 정보 접근 시도
- 404: 해당 id의 사용자 없음

400이랑 404를 뭉뚱그려 놓은 API를 종종 보는데, 클라이언트 입장에서는 둘이 완전히 다른 상황이다. 400은 요청 자체가 잘못된 거고, 404는 요청은 유효한데 데이터가 없는 것. 이걸 구분 안 해두면 클라이언트 재시도 로직을 짤 때 판단 기준이 없어진다. "에러 났으니까 다시 보내볼까?" vs "다시 보내도 소용없을 것 같은데?" 이 두 케이스를 같은 에러 코드로 처리하면 결국 사용자한테 이상한 경험을 준다. 이번에 오류 코드 정리하면서 이 부분도 명확하게 분리해뒀음.

레거시 리다이렉트 명세도 신규로 작성했는데, 이건 특히 기록이 중요한 영역이다. 리다이렉트 로직만 보면 "왜 두 URL이 같은 곳으로 향하지?" 싶다. 이유는 마이그레이션 과정에서 구 경로를 그대로 지원해야 해서인데, 그 맥락이 없으면 나중에 누군가 "이거 정리해도 되겠다" 싶어서 지웠다가 터진다. 한 줄짜리 배경 설명이 그 삽질을 막는다.

문서 항목 작업 내용
엔드포인트 커버리지 마이페이지 도메인 전체
파라미터 명세 필수/선택 구분 및 유효성 규칙 추가
오류 코드 상황별 분리 및 설명 추가
레거시 리다이렉트 URL 규칙 명세 신규 작성
수정 파일 1개

수정 파일이 1개인 건 집중해서 정리했다는 뜻이기도 하고, 변경 범위가 좁아서 리뷰하기 수월했다는 뜻이기도 하다.

문서 쓰다가 버그 잡는 이유

코드를 처음 짤 때는 흐름이 머릿속에 다 들어있어서 놓치기 쉬운 게 있다. 문서를 쓰는 건 "다른 사람에게 설명하는 연습"이기도 한데, 막상 설명하다 보면 스스로 "어, 이게 진짜 맞나?" 싶은 부분이 튀어나온다.

이번에도 그랬음. 응답 스펙을 문서에 적으면서 실제 코드 리턴값이랑 하나씩 맞춰보다가, 특정 조건에서 필드가 빠진 채로 내려오는 걸 발견했다. 그 조건이 자주 발생하는 케이스가 아니어서 테스트에서도 안 걸렸던 것. 문서를 안 썼으면 아마 한동안 못 잡았을 거임.

이걸 "문서화의 부수 효과"라고 부르는 사람이 있는데, 나는 이게 부수 효과라기보다 핵심 가치 중 하나라고 생각한다. 테스트 코드 짤 때도 비슷한 현상이 생기잖아. "이 함수를 어떻게 테스트하지?" 하다 보면 설계 자체가 이상한 걸 발견하게 되는 것처럼. 문서 작업도 결국 같은 원리임. 구현이 아닌 "이 API가 어떻게 쓰이는가"를 기준으로 다시 생각하게 강제되니까.

코드 리뷰보다 문서 작업이 버그를 먼저 잡는 경우도 있다. 코드 리뷰는 구현이 의도대로 됐는지를 보는 거지만, 문서 작업은 의도 자체가 맞는지를 다시 생각하게 만든다. 관점이 다른 거임.

'왜'를 기록한다는 것

'무엇을 하는 엔드포인트인지'는 경로 이름이랑 코드 보면 어느 정도 유추된다. 그런데 '왜 이 경로 구조로 설계했는지', '왜 이 파라미터는 선택값으로 뒀는지', '왜 이 에러는 403이 아니라 404인지'는 코드에 남지 않는다. 의사결정의 맥락이 날아가는 것.

6개월 뒤에 내가 짠 코드를 보면서 "내가 왜 이렇게 했지?" 싶은 순간을 한 번쯤 겪어봤을 거임. 그 순간에 배경이 한 줄이라도 있으면 완전히 다르다. 없으면 코드에서 의도를 역으로 추론하다가 잘못된 방향으로 수정하는 일이 생기고, 그게 새로운 버그의 씨앗이 된다.

레거시 리다이렉트처럼 "건드리면 터질 것 같아서 그냥 두는" 코드는 대부분 배경 설명이 없는 코드다. 무서워서 손을 못 대는 게 아니라, 왜 있는지 몰라서 못 건드리는 거임. 그 차이가 크다. 이유가 명확하면 "이 조건이 사라지면 이 리다이렉트도 없애도 된다"는 판단을 자신 있게 할 수 있다.

앞으로 새 API나 복잡한 로직을 추가할 때마다 최소한 의사결정 배경은 남기는 습관을 유지하려 한다. 지금 당장은 "당연히 아는 것"도 시간이 지나면 그 당연함이 희미해진다. 기록하는 데 걸리는 시간 대비 나중에 절약하는 시간이 훨씬 크다는 걸 이번에 다시 체감했음.

댓글 0

첫 댓글 달아줘.