이커머스 결제 API 문서 전면 보완으로 코드 불일치까지 해결
목차
결제 연동 플랫폼 API 문서를 처음부터 다시 쓴 날이었다. 정확히는 "전면 보완"이라고 표현했지만 실질적으로는 거의 새로 짠 것에 가까웠다. 기존에 있던 건 엔드포인트 경로 나열 수준이었고, 요청/응답 스펙도 없고, 오류 코드 정의는 아예 없었다. 결제 도메인 특성상 외부 시스템과 붙는 접점이 많아서 이 상태로는 협업이 불가능한 구조였다.
어디서부터 손댔나
문서화 범위를 먼저 정하고 시작했다. 엔드포인트 커버리지 전체를 목표로 잡고, 각 엔드포인트마다 아래 네 가지를 채우는 방식으로 진행했다.
- 경로, HTTP 메서드, 요청/응답 스펙
- 파라미터 명세 (필수/선택 여부, 타입, 유효성 규칙)
- 오류 코드 및 상황별 메시지
- 실제로 동작하는 요청/응답 샘플
예시 포맷은 이런 식으로 잡았다.
## GET /api/v1/users/{id}
### Request
- id (required): 사용자 식별자
### Response (200 OK)
{ "id": 1, "name": "홍길동", "status": "ACTIVE" }
### Errors
- 400: 파라미터 오류
- 401: 인증 필요
- 404: 리소스 없음
이 구조를 정해두면 나중에 추가 엔드포인트가 생겨도 일관성 있게 쓸 수 있다. 결제 도메인은 특히 오류 코드가 중요한데, 실패 케이스마다 왜 실패했는지 명확히 구분이 안 되면 클라이언트 측에서 오류 처리를 제대로 못 한다. 400 하나로 "뭔가 잘못됐어요"를 퉁치는 API는, 받는 쪽에서 결국 시행착오로 때워야 한다.
작업 결과 요약은 이렇다.
| 문서 항목 | 상태 |
|---|---|
| 엔드포인트 커버리지 | 전체 |
| 요청/응답 예시 | 추가 |
| 오류 코드 정의 | 완료 |
| 수정 파일 | 1개 |
수정 파일이 1개인 건 API 명세를 단일 파일로 관리하고 있기 때문이다. 스펙 파일이 여러 곳에 흩어져 있으면 나중에 갱신할 때 누락이 생기기 쉽다. 단일 파일 관리는 번거로울 것 같지만 유지 비용이 훨씬 낮다.
문서 쓰다가 코드 버그를 건진 이유
이번 작업에서 예상 못 한 수확이 있었다. 문서화하면서 코드와 실제 동작이 다른 부분 몇 군데를 발견해서 같이 수정했다. 이건 우연이 아니라 문서화가 강제하는 검토 사이클의 자연스러운 결과다.
코드를 처음 짤 때는 머릿속에 맥락이 가득 차 있다. "이 파라미터는 선택값인데 없으면 기본값을 쓰고..." 같은 것들이 다 기억에 있으니까 코드만 보면 된다. 그런데 문서에 파라미터를 하나씩 적다 보면 "이거 실제로 nullable 처리 돼 있나?" 하고 확인하게 된다. 그 순간 불일치가 드러난다.
이건 코드 리뷰나 테스트 코드 작성할 때도 비슷하게 작동한다. 내가 구현한 걸 다른 언어로 설명하려는 행위 자체가 빈틈을 노출시킨다. 결제 도메인처럼 엣지 케이스가 많은 곳에서는 이 효과가 더 두드러진다. 파라미터 조합, 금액 경계값, 부분 실패 처리 같은 것들은 구현할 때 당연하게 넘어간 부분에서 구멍이 나있는 경우가 많다.
실용적인 접근으로는 API 문서 작성을 스펙 리뷰 시점에 맞추는 게 좋다. 구현이 완전히 끝난 다음에 문서를 쓰는 게 아니라, 구현과 거의 동시에 문서를 초안으로 써두면 오류를 가장 빠른 시점에 잡는다. 코드가 리뷰로 넘어가기 전에 명세도 같이 넘기면 리뷰어가 의도를 훨씬 정확하게 파악한다.
'왜'를 남기지 않으면 나중에 후회한다
코드를 짤 때는 '나는 알고 있으니까 괜찮다'는 생각을 하기 쉽다. 근데 6개월 뒤 같은 코드를 보면 낯설어지는 경험을 한 번쯤은 해봤을 거다. 심지어 직접 짠 코드도.
문서화의 핵심은 '왜'를 기록하는 것이다. '무엇'은 코드를 보면 안다. 근데 '왜 이 구조로 설계했는가', '왜 이 파라미터는 선택값인가', '왜 이 오류는 500이 아니라 422인가' - 이건 코드에서 드러나지 않는다. 이 부분이 빠지면 나중에 변경할 때 잘못된 방향으로 가기 쉽다. 의도를 모르니까 제약을 건드려서는 안 되는데 건드리거나, 반대로 의도적으로 남긴 동작을 버그로 오해하고 고쳐버리거나.
결제 API는 이런 맥락이 특히 중요하다. 결제 흐름에는 외부 PG사 정책, 카드사 제약, 규제 요건 같은 것들이 복잡하게 얽혀 있어서, 코드만 봐서는 "이 로직이 비즈니스 규칙인지 기술적 제약인지 버그인지"를 판단하기 어렵다. 설계 배경이 문서에 없으면 다음 사람이 그걸 다시 파악하는 데 상당한 시간을 쓰게 된다. 내가 이미 쓴 시간을 또 쓰게 만드는 셈이다.
API나 복잡한 로직을 새로 만들 때마다 최소한 의사결정 배경은 남기려고 한다. 분량은 짧아도 된다. 한두 줄짜리 주석이라도, "이 필드가 optional인 이유는 레거시 호환성" 한 줄이 있으면 없는 것과 완전히 다르다.
댓글 0
첫 댓글 달아줘.