JSON은 종종 모호하거나 보장되지 않은 데이터를 보내게 됨. 필드 누락, 타입 오류, 키 오타, 문서화되지 않은 구조 등 다양한 문제가 생김. 하지만 Protobuf는 .proto 파일로 메시지 구조를 명확히 정의함으로써 이런 일이 불가능하다고 주장하는 글이 있었음. 그러나 이는 Protobuf의 철학을 오해한 것임. proto3에서는 required 필드 자체를 지원하지 않음. 공식 문서(Protobuf Best Practices)에서도 “required 필드는 해로워서 제거되었다”고 명시되어 있음. 결국 Protobuf 클라이언트도 JSON API처럼 방어적으로 작성해야 함
해당 블로그에는 비슷한 오해가 많음. 예를 들어 SVG 사용을 반대하는 글에서는 벡터 포맷의 자유로운 스케일링이라는 장점을 고려하지 않음
문제의 핵심은 언어나 클라이언트/서버 구현 차이일 뿐임. 나는 Go의 Marshalling 개념을 활용해 Gooey 프레임워크를 클라이언트에 사용 중임. Go의 한계를 극복하면 매우 타입 세이프하게 쓸 수 있음. 단, json:"-"로 private 필드를 막는 게 중요함. 내 프로젝트는 Gooey에서 볼 수 있음
이 글은 직렬화 포맷과 계약(Contract) 개념을 혼동하고 있음
네트워크 시스템에서는 인코딩 방식과 무관하게 데이터 불일치(Skew) 문제가 항상 존재함. 다만 Protobuf는 디코딩 후 정적 타입 객체를 제공함. JSON도 검증하면 되지만 대부분 그렇게 하지 않음. 결국 JSON 객체가 이리저리 변형되며 내부 구조를 아무도 확신할 수 없게 됨
아마 원글 작성자는 단순히 Protobuf에서 누락된 필드가 기본값으로 초기화된다는 점을 말하고 싶었던 것 같음. 이는 “required” 필드 개념과는 다름
압축된 JSON은 충분히 쓸 만하고, 초기 커뮤니케이션 비용이 낮음. 물론 필드가 빠지거나 타입이 바뀌면 문제가 생기지만, 완벽히 타입화된 구조를 설계하고 버전 동기화를 위한 프로세스를 만드는 사람들은 대부분 실패함. 결국 인간의 비용이 낮은 쪽이 승리함. 그래서 JSON은 더 낮은 인간 커뮤니케이션 비용을 가진 대체제가 나오기 전까지는 사라지지 않을 것임
맞음. 대부분의 아키텍트는 gRPC 같은 명확한 필요가 없으면 proto를 고려하지 않음. console.log()로 바로 디버깅할 수 있는 대안이 나오기 전까지 JSON은 대체되지 않을 것임
디버깅도 JSON의 강점임. 그냥 열어서 읽으면 됨. 반면 Protobuf는 툴링이 필요함
맞는 말임. 하지만 사람들은 설계 단계에서 15분 더 투자하기보다, 나중에 3개월 동안 문제를 되짚는 걸 택함
JSON이 COBOL처럼 완전히 사라지진 않겠지만, 새 프로젝트에서는 굳이 쓸 이유가 없음
Protobuf는 완벽하지 않음. 서버와 클라이언트가 다른 시점에 배포되어 스펙 버전이 다르면 안전성이 깨짐. ID 재사용 금지, unknown-field 복사 등으로 완화할 수 있지만, 분산 시스템은 본질적으로 복잡함. 그래도 protobuf3는 protobuf2의 문제를 많이 해결했음. 예전엔 기본값이 설정된 건지 누락된 건지 구분이 안 됐는데, 이제는 message 타입을 쓰면 해결됨
JSON이든 Protobuf든 버전 호환성 테스트를 CI 파이프라인에서 강제해야 안전함
어떤 타입 시스템도 네트워크를 통과하면 깨짐
글에서 “초고효율”이라 했지만 gzip 언급이 없음. 대부분의 텍스트 데이터는 이미 자동 압축되어 전송됨. 따라서 Protobuf는 gzip된 JSON과 비교해야 함
나도 여러 바이너리 포맷을 테스트했지만, 결국 gzipped JSON이 압도적으로 효율적이었음
JSON의 단점은 직렬화/역직렬화 속도임. 나머지는 점진적으로 해결 가능함
스트리밍 Brotli/zstd JSON/HTML도 고려할 만함. 연결 유지 중 압축 윈도우를 활용할 수 있음
더 나은 프로토콜을 옹호하는 건 좋지만, Protobuf가 효율성과 사용성 모두에서 JSON을 대체한다고 보긴 어려움. Protobuf는 엄격한 스키마 때문에 JSON이 잘하는 영역을 놓침. 오히려 CBOR가 JSON 대체로 더 적합함. CBOR은 JSON처럼 유연하면서도 더 간결한 인코딩을 가짐
하지만 Protobuf의 엄격한 스키마가 오히려 장점일 수도 있음. 대부분의 API는 JSON 스키마를 공개하지 않기 때문임. 나는 ajv나 superstruct로 검증했지만, Protobuf는 그럴 필요가 없음
브라우저가 CBOR API를 직접 지원하면 좋겠음. 내부 구현은 이미 있으니 어렵지 않을 것임
1984년의 ASN.1은 이미 Protobuf가 하는 일을 더 유연하게 수행함. DER 인코딩을 쓰면 그렇게 나쁘지 않음. ASN.1 DER 예시를 보면 됨. Protobuf는 달성하는 것에 비해 너무 복잡함
ASN.1은 기능이 너무 많음. 모든 기능을 지원하면 과도하게 복잡한 라이브러리가 되고, 일부만 지원하면 더 이상 표준 ASN.1이 아님
나는 ASN.1 DER을 선호함. 직접 C로 구현한 DER 인코더/디코더를 FOSS로 공개했음. 확장형 “ASN.1X”를 만들어 JSON의 데이터 모델을 완전히 포함시킴
하지만 SNMP 같은 시스템에서 ASN.1의 과도한 유연성은 오히려 문제였음. 제조사마다 제멋대로 확장함
Google 내부에서도 Protobuf 직렬화/역직렬화에 CPU를 많이 소모했음
ASN.1은 과설계(overengineered) 되어 지원이 어려움. 상속 같은 기능은 불필요함
나는 프로덕션 시스템 전체를 Protobuf로 구성했는데, 관리 자체가 고통스러웠음. 기술적으로는 좋아 보이지만 실제로는 JSON이 훨씬 단순함
JSON의 가독성과 디버깅 편의성은 과소평가할 수 없음. 대부분의 팀은 단기 효율을 위해 JSON을 선택함
어떤 문제가 있었는지 궁금함. 내 경험상 Protobuf의 불편함보다 JSON의 데이터 손상 위험이 더 큼. Protobuf는 컴파일 에러로 잡히지만 JSON은 프로덕션에서 터짐
Protobuf는 훌륭하지만 zero-copy를 지원하지 않는 게 아쉬움. Cap’n Proto 같은 포맷은 직렬화/역직렬화 병목을 없애줌
하지만 실제로는 zero-copy가 오히려 느릴 수도 있음. 캐시 내 복사는 거의 공짜지만, 동적 구조를 직접 다루면 오버헤드가 생김. 대부분의 경우 한 번 복사(one-copy)만으로 충분함
Cap’n Proto의 마케팅에서 나온 주장일 뿐, 실제로는 성능 차이가 미미함. 두 포맷 모두 네이티브 타입 ↔ 바이너리 변환이 필요함. 페이로드에 따라 성능은 비슷함
이건 포맷의 문제가 아니라 라이브러리 구현 문제일 수도 있음
나는 NodeJS 프로젝트에서 .proto로 전체 API를 정의하고, Content-Type에 따라 proto 또는 JSON으로 응답하는 서버를 만들었음. Swagger보다 훨씬 구조적임. 다만 Google이 이런 기능을 공식 라이브러리로 제공하지 않은 게 아쉬움. gRPC는 HTTP/2 의존성 때문에 불편함. 참고로 Text proto는 최고의 정적 설정 언어라고 생각함
이런 목적이라면 Twirp가 적합함. Protobuf나 JSON을 단순한 HTTP 위에서 다룸
Hacker News 의견
JSON은 종종 모호하거나 보장되지 않은 데이터를 보내게 됨. 필드 누락, 타입 오류, 키 오타, 문서화되지 않은 구조 등 다양한 문제가 생김. 하지만 Protobuf는
.proto파일로 메시지 구조를 명확히 정의함으로써 이런 일이 불가능하다고 주장하는 글이 있었음. 그러나 이는 Protobuf의 철학을 오해한 것임.proto3에서는 required 필드 자체를 지원하지 않음. 공식 문서(Protobuf Best Practices)에서도 “required 필드는 해로워서 제거되었다”고 명시되어 있음. 결국 Protobuf 클라이언트도 JSON API처럼 방어적으로 작성해야 함json:"-"로 private 필드를 막는 게 중요함. 내 프로젝트는 Gooey에서 볼 수 있음압축된 JSON은 충분히 쓸 만하고, 초기 커뮤니케이션 비용이 낮음. 물론 필드가 빠지거나 타입이 바뀌면 문제가 생기지만, 완벽히 타입화된 구조를 설계하고 버전 동기화를 위한 프로세스를 만드는 사람들은 대부분 실패함. 결국 인간의 비용이 낮은 쪽이 승리함. 그래서 JSON은 더 낮은 인간 커뮤니케이션 비용을 가진 대체제가 나오기 전까지는 사라지지 않을 것임
console.log()로 바로 디버깅할 수 있는 대안이 나오기 전까지 JSON은 대체되지 않을 것임Protobuf는 완벽하지 않음. 서버와 클라이언트가 다른 시점에 배포되어 스펙 버전이 다르면 안전성이 깨짐. ID 재사용 금지, unknown-field 복사 등으로 완화할 수 있지만, 분산 시스템은 본질적으로 복잡함. 그래도
protobuf3는protobuf2의 문제를 많이 해결했음. 예전엔 기본값이 설정된 건지 누락된 건지 구분이 안 됐는데, 이제는message타입을 쓰면 해결됨글에서 “초고효율”이라 했지만 gzip 언급이 없음. 대부분의 텍스트 데이터는 이미 자동 압축되어 전송됨. 따라서 Protobuf는 gzip된 JSON과 비교해야 함
더 나은 프로토콜을 옹호하는 건 좋지만, Protobuf가 효율성과 사용성 모두에서 JSON을 대체한다고 보긴 어려움. Protobuf는 엄격한 스키마 때문에 JSON이 잘하는 영역을 놓침. 오히려 CBOR가 JSON 대체로 더 적합함. CBOR은 JSON처럼 유연하면서도 더 간결한 인코딩을 가짐
1984년의 ASN.1은 이미 Protobuf가 하는 일을 더 유연하게 수행함. DER 인코딩을 쓰면 그렇게 나쁘지 않음. ASN.1 DER 예시를 보면 됨. Protobuf는 달성하는 것에 비해 너무 복잡함
나는 프로덕션 시스템 전체를 Protobuf로 구성했는데, 관리 자체가 고통스러웠음. 기술적으로는 좋아 보이지만 실제로는 JSON이 훨씬 단순함
Protobuf는 훌륭하지만 zero-copy를 지원하지 않는 게 아쉬움. Cap’n Proto 같은 포맷은 직렬화/역직렬화 병목을 없애줌
나는 NodeJS 프로젝트에서
.proto로 전체 API를 정의하고, Content-Type에 따라 proto 또는 JSON으로 응답하는 서버를 만들었음. Swagger보다 훨씬 구조적임. 다만 Google이 이런 기능을 공식 라이브러리로 제공하지 않은 게 아쉬움. gRPC는 HTTP/2 의존성 때문에 불편함. 참고로 Text proto는 최고의 정적 설정 언어라고 생각함내가 꿈꾸는 바이너리 포맷은 스키마 기반이면서도 메시지 안에 스키마를 포함하는 형태임. 이렇게 하면 vim 플러그인으로 바로 읽을 수 있음. 수백만 개 객체를 다룰 때 1KB의 스키마를 2GB 메시지에 붙이는 건 큰 부담이 아님