채널 API 에서 어떤 필드가 서버 쪽에서 만들어지는 값인지를 알아야 했다. GET /products/{id} 응답에는 있고 POST /products 스펙에는 없는 필드를 찾으면 그것이 답일 것으로 보였다.
Table of contents
Open Table of contents
배경 — 조회에는 있고 등록에는 없는 필드
두 스펙의 필드명을 뽑아 diff 로 대조해 보니 한쪽에만 있는 필드가 지나치게 많았다. 서버 쪽에서 자동으로 만들어지는 값이 그렇게 많을 리는 없다고 봤다.
결과로 나온 숫자가 이상하면 결과보다 비교 방법 자체를 먼저 의심해야 한다. 그래서 결과를 더 파기 전에 이 대조가 기대고 있는 전제부터 확인하기로 했다.
원인 — 리소스가 달랐던 두 스펙
확인해 보니 조회하는 쪽 리소스와 등록하는 쪽 리소스가 애초에 다른 것이었다. 한쪽은 여러 단일 상품을 묶은 ProductGroup 이고 다른 한쪽은 그 안의 Product 였다.
구조가 다른 두 스펙을 대조하면 한쪽에만 있다는 사실이 서버 생성인지 구조 차이인지를 구분해 주지 못한다. 그 상태에서 뽑아 놓은 목록은 어느 항목도 신뢰할 수 없었다.
조치 — 비교 가능한 층위로 좁히기
두 가지 방법이 있었는데 그룹 응답을 평탄화해서 전체를 다시 대조하는 것과 그룹 응답 안의 products[] 와 등록 스펙의 Product 처럼 대응되는 층끼리만 놓고 비교하는 것이다. 뒤쪽을 골랐다. 이유는 평탄화하면 그룹 층의 필드가 어느 상품 것인지 알 수 없어 같은 잡음이 다시 생겨서다. 대신 그룹 층의 필드는 이번 결론에서 빠지는 것을 감수했다. channels[] 도 같은 층위에 있는 것끼리 짝을 지어서 항목별로 대조했다.
그 범위 안에서 나온 created_at 과 product_no 같은 필드만 서버가 만드는 값으로 확정해서 적었다. 전체를 한꺼번에 비교하면 구조 차이에서 오는 잡음이 결론을 통째로 덮는다.
주의 — 확정과 미확인의 분리
확정된 목록과는 별개로 두 스펙 어디에도 정의가 나오지 않는 필드도 있었다. 실제 GET 응답에는 나오는데 어느 스펙 문서에도 안 적혀 있는 것들이었다.
그것들은 아마 서버 생성일 것이라고 적지 않고 SPEC.md 에 미확인으로 두면서 어느 스펙을 더 봐야 하는지를 적었다. 이 문서는 다른 사람이 구현할 때 쓰이므로 서버 생성이라고 적으면 그 사람이 값을 안 넣고 그것이 틀리면 필수 값이 빠진 채 POST 가 나간다.
검증 — 비교 전에 확인할 세 가지
이 건에서 남은 것은 대조 전에 비교가 가능한지를 먼저 확인한다는 순서였다. 같은 리소스인지와 같은 층위인지와 같은 v1 버전인지를 확인하는 것 셋이다.
셋 중 하나라도 다르면 필드명 대조만으로는 아무 결론도 나오지 않는다. 그럴 때는 비교가 가능한 부분집합을 먼저 정하고 그 안에서만 확정으로 적는다.
정리
- 조회 리소스와 등록 리소스가 다른 것일 수 있다
- 숫자가 이상하면 결과가 아니라 비교 방법을 의심한다
- 구조가 다르면 한쪽에만 있다는 사실이 아무것도 못 가른다
- 대응되는 층끼리만 놓고 대조한다
- 그 범위에서 나온 것만 확정으로 적는다
- 확정 못 한 것은 그럴듯해도 미확인으로 적는다
- 확정과 추측을 섞으면 문서 전체의 신뢰가 떨어진다
- 대조 전에 같은 리소스와 층위와 버전인지 확인한다