에듀테크 프로젝트 대시보드
gRPC & Protocol Buffers
REST API는 보통 사람이 읽을 수 있는 JSON 텍스트를 주고받는다. gRPC는 대신 Protocol Buffers(Protobuf)라는 스키마 기반 바이너리 포맷으로 데이터를 직렬화하고, HTTP/2 위에서 원격 함수를 호출하듯 통신한다. 필드마다 이름 문자열을 반복해서 보내는 JSON과 달리, Protobuf는 미리 정의한 필드 번호만 태그로 실어 보내기 때문에 같은 데이터를 훨씬 작은 바이트 수로 표현할 수 있다. 아래에서 직접 값을 바꿔가며 그 차이를 계산해보자.
아래 값을 바꾸면 JSON 문자열과 Protobuf 바이너리 인코딩(태그+varint+length-delimited)의 실제 바이트 수를 각각 계산한다.
Protobuf가 --% 더 작음 (같은 데이터, 같은 의미)
| 필드 | 태그 (필드#<<3 | wire type) | 값 인코딩 | 바이트 |
|---|
서버와 클라이언트가 공유하는 .proto 파일 하나로 메시지 구조와 원격 함수 시그니처를 정의하면, protoc 컴파일러가 Python, Go, Java, C++ 등 여러 언어의 클라이언트/서버 코드를 자동 생성한다.
syntax = "proto3"; message User { int32 id = 1; // 필드 번호 1 (와이어 타입 0: varint) string name = 2; // 필드 번호 2 (와이어 타입 2: length-delimited) bool active = 3; // 필드 번호 3 (와이어 타입 0: varint) } service UserService { // 단항 RPC: 요청 1개 → 응답 1개 rpc GetUser(UserRequest) returns (User); // 서버 스트리밍: 요청 1개 → 응답 스트림 rpc WatchUsers(UserRequest) returns (stream User); }
gRPC는 HTTP/2의 스트림 위에서 요청/응답을 독립적으로 여러 번 주고받을 수 있어, REST 한 번의 요청-응답을 넘어선 4가지 통신 패턴을 지원한다.
요청 1개를 보내고 응답 1개를 받으면 끝 — REST와 동일한 흐름.
| REST + JSON | gRPC + Protobuf | |
|---|---|---|
| 전송 형식 | 텍스트 (사람이 읽기 쉬움) | 바이너리 (스키마 필요) |
| 스키마 | 선택적 (OpenAPI 등) | .proto로 강제, 버전 관리 용이 |
| 전송 프로토콜 | 보통 HTTP/1.1 | HTTP/2 (멀티플렉싱) |
| 스트리밍 | 어려움 (SSE/WebSocket 별도) | 양방향 스트리밍 네이티브 지원 |
| 브라우저 직접 호출 | 가능 | 불가 — grpc-web 프록시 필요 |
| 적합한 상황 | 공개 API, 사람이 디버깅 | 내부 마이크로서비스 간 고성능 통신 |