외부 시스템의 수정 창구를 붙이면서 이름만 바꾸는 요청이 오면 이름만 보내면 될 것으로 생각했다. 그런데 규격을 읽기 전에 문답 자료를 먼저 훑어보다가 그렇지 않다는 것을 알았다. 공식 답변에 「요청 데이터에 해당 필드가 포함되지 않는다면 제거되는 방식으로 동작합니다」라고 적혀 있었다. 부분 수정인 PATCH 가 아니라 보낸 것으로 자원 상태를 통째로 갈아 끼우는 PUT 이었다.
Table of contents
Open Table of contents
안 보낸 필드가 지워진다
RFC 7231 이 PUT 을 보낸 표현으로 자원 상태를 대체하는 것으로 정의하므로 요청에 안 담긴 필드는 새 상태에 없는 것이 되어 지워진다. 이름만 보내면 나머지가 전부 비워지는 결과가 된다.
더 나쁜 것은 그때 오류가 나지 않는다는 점이었다. 요청은 200 이나 204 로 돌아오고 값만 사라진다. 같은 내용의 문의가 여러 건 올라와 있었다. 이름이 「수정 API」이니 다들 부분 수정으로 읽은 것이다.
설계가 통째로 달라졌다
이 사실을 알고 나니 우리 쪽 설계가 완전히 달라졌다.
[처음 생각] 수정할 필드만 보낸다
[실제 설계] 조회 → 전체 필드 재구성 → 변경분 반영 → 전송
바꿀 값만 보내는 것이 아니라 먼저 GET 으로 현재 값을 받아 전체를 만들고 그중 바꿀 것만 갈아 끼워 PUT 해야 한다.
GET 이 한 단계 늘어나므로 실패 지점도 늘고 그 사이에 값이 바뀔 가능성도 생긴다. 그래도 그렇게 하지 않으면 매번 값이 지워진다. 창구의 성격 하나가 우리 쪽 처리 구조 전체를 정하고 있었다.
주의 — 예외 필드 다섯
문답 자료를 더 읽어 보니 전체 치환이라도 예외인 필드가 다섯 있었다.
분류 식별자
상세 내용
재고
정보 고시
검색 정보
이것들은 안 보내도 기존 값이 유지된다.
그런데 그 목록이 규격 문서에는 없고 문답 답변에만 흩어져 있었다. 그래서 전부 모아 표로 정리했다. 예외를 모르면 조회한 값을 전부 실어 보내게 되는데 그것이 문제를 만드는 필드가 따로 있었다.
오히려 빼야 하는 필드
예외 중 하나는 반대 방향이었다. 특정 편집기로 작성한 상세 내용은 오히려 요청에서 빼야 기존 형식이 보존됐다.
[보내면] 형식이 깨진다
[안 보내면] 그대로 유지된다
조회 응답에는 들어 있지만 수정 요청에는 넣으면 안 되는 값이었다.
또 하나는 상대가 자동으로 계산하는 값이라 보낼 필요가 없었다. 조회한 것을 그대로 되돌려 보내는 단순한 방식이 이 셋 때문에 성립하지 않았다. 필드마다 보낼지 말지를 정한 표가 결국 필요했다.
전용 창구와 안 보냄의 뜻
일부만 바꾸는 전용 창구가 따로 있는지도 확인했더니 몇 가지 항목에 대해서는 있었다. 그런 것이 있으면 전체 치환보다 훨씬 안전하다.
다만 전용 창구에는 다른 제약이 붙어 있어서 그것도 함께 확인해야 했다. 정리하면 PUT 창구에서는 안 보내는 것이 지우라는 명령과 같다. 보내지 않음이 무언가를 뜻하는 구조에서는 무엇을 안 보내는지가 무엇을 보내는지만큼 중요했다.
정리
- 수정 창구가
PATCH가 아니라PUT일 수 있다 - 안 보낸 필드가 지워지고 오류도 안 난다
- 설계가
GET과 재구성과PUT으로 늘어난다 - 조회가 늘면 실패 지점과 경합 가능성도 는다
- 안 보내도 유지되는 예외 필드가 있다
- 보내면 오히려 오류가 나는 필드도 있다
- 자동 계산되는 값은 보낼 필요가 없다
PUT에서는 안 보냄이 그대로 명령이다