gRPC는 다른 프로세스·서버의 함수를 내 함수처럼 부르는 RPC 프레임워크다. 인터페이스를 Protocol Buffers(protobuf)로 정의하고, 그 정의에서 여러 언어의 클라이언트·서버 코드를 생성하며, HTTP/2 위에서 바이너리로 통신한다.
syntax = "proto3";
service UserService {
rpc GetUser (GetUserRequest) returns (User);
rpc WatchUsers (WatchRequest) returns (stream User); // 서버 스트리밍
}
message GetUserRequest { int64 id = 1; }
message User { int64 id = 1; string name = 2; }구성 요소
- protobuf: 인터페이스 정의 언어(Interface Definition Language, IDL)이자 직렬화(serialization) 형식. 필드 번호로 인코딩해 JSON보다 작고 빠르며, 번호를 지키면 필드 추가에도 하위 호환된다
- 코드 생성:
.proto에서 스텁(stub)을 만들어 타입이 맞지 않는 호출을 컴파일 단계에서 잡는다 - HTTP/2: 바이너리 프레이밍(binary framing), 연결 하나에 여러 요청을 동시에 싣는 멀티플렉싱(multiplexing), 헤더 압축(header compression)
- 통신 방식 4가지: 단항(unary), 서버 스트리밍(server streaming), 클라이언트 스트리밍(client streaming), 양방향 스트리밍(bidirectional streaming)
- 채널(channel): 서버로의 연결을 추상화한 객체. 재사용한다
- deadline·취소: 호출마다 마감 시간을 주면 넘었을 때 양쪽에서 취소된다. 다운스트림 호출이 업스트림을 붙잡는 일을 막는다(업스트림과 다운스트림)
- 인터셉터(interceptor): 인증·로깅 같은 횡단 관심사(cross-cutting concern)를 호출 앞뒤에 끼운다
REST·GraphQL과 비교
| REST | GraphQL | gRPC | |
|---|---|---|---|
| 계약 | 관례·OpenAPI | 스키마 | .proto |
| 형식 | 주로 JSON | JSON | 바이너리 |
| 브라우저 | 그대로 | 그대로 | 프록시(gRPC-Web) 필요 |
| 강점 | 단순, 캐시 | 클라이언트가 필드 선택 | 서비스 간 고성능·스트리밍 |
브라우저는 HTTP/2 프레임을 직접 다루지 못해 gRPC를 바로 쓸 수 없으므로, 주로 마이크로서비스 사이 내부 통신에 쓴다. NestJS도 gRPC 트랜스포트를 공식 지원한다. 같은 함수 호출처럼 보여도 네트워크는 실패한다는 점을 잊지 않게 하는 것이 RPC 설계의 핵심이다(누수 추상화의 법칙).
출처: gRPC 소개 · gRPC 핵심 개념: RPC 종류 · Deadlines · Channels