필드 번호를 바꿨더니 옛 클라이언트가 조용히 틀린 값을 읽었다 · 번호는 이름보다 오래 산다 · 퀴즈
퀴즈: 번호는 이름보다 오래 산다
문항 6개. 정답과 해설은 풀어 본 뒤에 보여 드립니다.
옛 클라이언트가 `int32 id = 1; int32 qty = 2;` 를 믿고 있는데 새 스키마가 두 번호를 맞바꿨다. 옛 클라이언트에서 일어나는 일은?
- 와이어 타입이 같아 오류 없이 id 자리에 qty 값을 읽는다
- 필드 이름이 달라 파싱 오류가 나고 호출이 INTERNAL 로 끝난다
- 두 필드가 모두 알 수 없는 필드로 분류돼 기본값 0 이 된다
- 파서가 새 .proto 를 감지해 자동으로 매핑을 바꾼다
필드 `note = 3` 을 지울 때 문서가 권하는 것은?
- 3 번을 비워 두었다가 다음 새 필드에 재활용한다
- 필드를 주석 처리만 해 두면 컴파일러가 번호를 기억한다
- `reserved 3;` 과 `reserved "note";` 를 남겨 재사용을 막는다
- 남은 필드의 번호를 1 부터 다시 매겨 빈틈을 없앤다
proto3 에서 라벨 없는 `int32 qty` 에 0 을 설정해 직렬화하면?
- `10 00` 두 바이트로 실려 받는 쪽이 0 을 받았음을 안다
- 기본값이라 레코드가 실리지 않아 안 보낸 것과 구별되지 않는다
- 필드 번호만 실리고 값은 생략되어 한 바이트가 된다
- has_qty 가 true 로 함께 직렬화되어 구별할 수 있다
`optional` 을 붙여 명시적 presence 로 바꾸는 것이 특히 필요한 상황은?
- 메시지 크기를 줄여야 해서 기본값을 더 자주 생략하고 싶을 때
- 필드 번호를 바꾸면서도 옛 클라이언트와 호환을 유지해야 할 때
- 문자열 필드의 UTF-8 검증을 파서가 대신하게 하고 싶을 때
- 부분 갱신에서 "이 값을 0 으로 바꿔라" 를 전달해야 할 때
문서가 조건부 호환으로 분류하는 타입 변경은?
- `int32` 를 `int64` 로 — 큰 값은 잘리므로 배포 순서를 통제해야 한다
- `int32` 를 `string` 으로 — 와이어 타입이 같아 그대로 읽힌다
- `sint32` 를 `int32` 로 — 둘 다 varint 라 값이 같다
- `string` 을 `fixed32` 로 — 길이가 고정이라 더 안전하다
필드 번호로 쓸 수 있는 범위와 예외는?
- 1 부터 65,535 까지, 0 은 기본값 표시용으로 예약
- 1 부터 2,147,483,647 까지, 제한 없음
- 1 부터 536,870,911 까지, 19,000~19,999 는 구현 예약
- 0 부터 4,294,967,295 까지, 짝수는 packed 용으로 예약