새 도매 채널의 주문 수집 어댑터를 만들게 되어 공식 문서를 읽고 계획을 세웠다. 검토 과정에서 문서와 실제 응답이 어긋나는 지점이 줄줄이 나왔다.
Table of contents
Open Table of contents
문제 — 문서와 다른 인증 방식
문서 앞부분은 HMAC 서명 기반 인증처럼 서술돼 있었는데 실제로는 login 을 호출해 session_id 를 받는 방식이었다. 만료 시간도 하루에 가까워서 매 요청 서명을 만드는 구조와는 전혀 달랐다.
인증 방식 하나가 캐시 위치와 만료 관리와 동시 요청 처리까지 구조 전체를 정하므로 구현 중에 알면 갈아엎어야 한다. 그래서 이 항목을 확인하는 것이 계획 단계의 첫 일이 됐다.
선언과 다른 타입
문서에 int 로 선언된 qty 와 price 가 실제 응답에서는 전부 "12" 같은 문자열로 왔다. 타입이 엄격한 언어로 짜면 역직렬화 단계에서 바로 실패한다.
그래서 숫자로 오든 문자열로 오든 (int) 로 받는 역직렬화를 OrderAdapter 에 준비했다. 혹시 몰라서가 아니라 실제 응답을 확인하고 넣은 대비였다.
원인 — 키 이름으로 갈리는 성공과 실패
응답의 성공과 실패가 HTTP 상태 코드가 아니라 최상위 키 이름으로 갈리고 있었다. result 키가 있으면 성공이고 error 키가 있으면 실패이며 둘 다 200 으로 온다.
그러면 ChannelClient 가 result 안쪽만 꺼내 돌려주면 호출 쪽이 성공과 실패를 판별할 수단을 잃는다. 두 가지 방법이 있었는데 ChannelClient 가 error 를 보면 예외를 던지고 result 안쪽만 돌려주는 것과 응답 전체를 돌려주고 OrderAdapter 가 판별하는 것이다. 앞쪽을 골랐다. 이유는 채널마다 다른 성공과 실패 규약을 아는 곳이 클라이언트 하나여야 해서다. 대신 예외 객체에 원래 응답 본문을 통째로 실어야 하는 것을 감수했다.
주의 — 엔드포인트마다 뜻이 다른 필드
가장 나빴던 것은 같은 이름의 total_amount 가 orders/list 와 orders/{id} 에서 의미가 서로 반대라는 점이었다. 이름을 믿고 쓰면 어느 한쪽은 반드시 틀린 값을 담게 된다.
금액이라 틀려도 오류가 안 나고 숫자가 들어가 계산도 되므로 값만 조용히 틀린다. 그래서 그 필드를 쓰지 않고 items[].price 와 qty 를 곱해 합산한 총액을 재계산하기로 했다.
결론 — 구현 전 목록이 하는 일
이 밖에도 데이터가 없을 때 result 가 빈 배열이 아니라 빈 문자열이라는 것과 주문 번호 형식이 엔드포인트마다 다르다는 것과 buyer 와 receiver 가 별개 엔티티라는 것을 확인했다. 도매라 대신 주문하는 경우가 많아 둘을 혼동하면 배송지가 틀린다.
일곱 개가 전부 구현 전 검토에서 나왔고 구현 단계에서는 확인만 했다. 구현하면서 하나씩 만났으면 구조를 갈아엎거나 이미 저장된 값이 틀리거나 잘못 배송되는 결과가 됐을 것이다.
정리
- 외부 인터페이스는 문서와 실제 응답이 어긋나는 지점부터 목록으로 만든다
- 인증 방식 하나가 구조 전체를 정한다
- 정수로 선언된 필드가 문자열로 올 수 있다
- 성공과 실패가 키 이름으로 갈리면 그 규약을 아는 계층에서 예외로 바꾼다
- 데이터 없음의 구조가 있음과 다를 수 있다
- 같은 이름의 필드가 엔드포인트마다 의미가 다를 수 있다
- 신뢰할 수 없는 금액 필드는 쓰지 않고 재계산한다
- 이 목록은 구현 전 검토에서 만들어야 값이 있다