시세 제공사에 우리 마켓 정보를 올리는 파트너 API 클라이언트를 만들면서 PUT /markets/{id} 에 모든 필드를 현재 값으로 채워 보내는 것이 안전하다고 봤다. 안 바꿀 항목도 지금 값을 그대로 실으면 어긋날 일이 없을 것 같았다.
Table of contents
Open Table of contents
배경 — 모든 필드를 채워 보내는 안전
이 방식은 빠뜨린 필드 때문에 값이 지워지는 사고를 막아 준다. RFC 7231 이 정한 PUT 은 자원의 상태를 요청에 실린 표현으로 통째로 바꾸는 것이라, 표준대로면 전부 채워 보내는 것이 맞다.
실제로 이 API 의 어떤 필드는 생략하면 그대로 유지되고 빈 값을 보내면 지워졌다. 표준과 달리 필드 단위로 동작하는 것인데, 그렇다면 더더욱 전부 채워 보내는 쪽이 방어적으로 보였다. 그런데 이 전제가 필드마다 성립하지는 않았다.
원인 — 값이 같아도 상태가 바뀐다
질의응답을 뒤지다 description 을 같은 값으로 다시 보내면 편집기로 만든 설명이 직접 입력 모드로 바뀐다는 답변을 봤다. 그리고 그 전환은 되돌릴 수 없었다.
저쪽이 값이 아니라 그 필드가 요청에 들어 있는지를 보고 description_mode 를 정하기 때문이다. 그러면 값을 그대로 실어도 상태가 바뀌므로 생략하는 쪽이 유지가 된다.
조치 — 필드별 표를 만드는 이유
앞서 확인한 fee_rate 는 생략이 유지이고 빈 값이 제거였는데 description 은 포함이 전환이고 생략이 유지였다. 방향이 서로 반대라 일괄 규칙을 만들 수가 없었다.
두 가지 방법이 있었다. RequestBuilder 의 기본값을 전부 채움으로 두고 description 만 예외로 빼는 것과, 필드별로 생략과 빈 값과 동일 값 재전송의 결과를 칸으로 나눈 표를 만들고 빌더가 그 표를 읽게 하는 것이다. 뒤쪽을 골랐다. 이유는 예외가 하나뿐이라는 보장이 없어서다. 대신 필드가 늘 때마다 표를 채워야 하는 것을 감수했다.
개발 중에는 안 걸리는 상한
같은 조사에서 GET /markets 에 한 번에 받을 수 있는 건수 상한 limit=100 이 있다는 것도 확인했다. 초과분은 응답에 담겨 오는 next_cursor 를 다음 호출에 넣어야 받아진다.
개발 중에는 데이터가 적어 상한에 안 걸리므로 구현하지 않아도 통과한다. 운영에서 마켓이 쌓인 어느 날 초과분이 조용히 잘리므로 반드시 구현해야 하는 종류였다.
없는 기능 목록
문서의 필수 표기가 스키마 필수만 나타내고 fee_type=percent 일 때 fee_rate 가 필요해지는 조건부 필수는 안 적혀 있다는 것도 확인했다. 등록 마켓이 하나도 없으면 토큰 발급 자체가 거부된다는 것도 답변에만 있었다.
마지막으로 아예 제공되지 않는 기능을 목록으로 정리했는데 마켓 삭제와 로고 교체와 변경 이력 조회 같은 것들이었다. 이 목록을 기획 단계에 넣지 않으면 만들다가 없다는 것을 알고 이미 만든 것을 뜯게 된다.
정리
- 같은 값을 다시 보내도 상태가 바뀔 수 있다
- 저쪽이 값이 아니라 필드의 존재를 보고 판단하기 때문이다
- 그 필드는 생략하는 것이 유지이므로
RequestBuilder의 기본값이 반대가 된다 - 필드마다 방향이 달라 일괄 규칙을 만들 수 없다
- 생략과 빈 값과 동일 값 재전송을 칸으로 나눈 표를 만든다
next_cursor이어받기는 개발 중에 안 걸리므로 반드시 구현한다- 문서의 필수 표기는 조건부 필수를 포함하지 않는다
- 없는 기능 목록을 기획 단계에 넣는다