gRPC vs REST
IntermediateREST uses HTTP/1.1 with JSON — human-readable, universally supported, but verbose. gRPC uses HTTP/2 with Protocol Buffers — binary, strongly typed, 5–10× faster, and supports bidirectional streaming.
Overview
REST (Representational State Transfer) over HTTP/1.1 with JSON is the dominant style for public APIs — easy to consume, debuggable with curl, and supported by every language. But JSON is verbose (field names repeated in every response) and HTTP/1.1 lacks multiplexing. gRPC, created by Google, addresses these shortcomings: it uses Protocol Buffers (protobuf) for binary serialisation (3–10× smaller payloads), HTTP/2 for multiplexed streams, and generates strongly-typed client/server stubs from a .proto schema. gRPC supports four interaction patterns: unary (like REST), server streaming, client streaming, and bidirectional streaming. It is the default for inter-service communication in Google, Netflix, and most Kubernetes-native microservices. The trade-off: gRPC is harder to debug (binary, not human-readable), requires HTTP/2 (complicates load balancer setup), and is not supported natively in browsers (requires gRPC-Web proxy). REST remains preferable for public-facing APIs; gRPC shines for internal service-to-service communication.
Protocol Buffers and Code Generation
gRPC defines services in a .proto file. The protoc compiler generates type-safe client and server stubs in any language. The binary wire format is compact and fast to serialise/deserialise compared to JSON text parsing.
// user.proto — service definition
syntax = "proto3";
package user;
service UserService {
rpc GetUser(GetUserRequest) returns (UserResponse); // Unary
rpc ListUsers(ListUsersRequest) returns (stream UserResponse); // Server streaming
rpc UpdateUsers(stream UpdateUserRequest) returns (UpdateSummary); // Client streaming
rpc Chat(stream ChatMessage) returns (stream ChatMessage); // Bidirectional
}
message GetUserRequest { string user_id = 1; }
message UserResponse {
string id = 1;
string name = 2;
string email = 3;
int64 created = 4;
}
// Compile: protoc --java_out=. --grpc-java_out=. user.proto
// Generates: UserServiceGrpc.java (stubs), UserProto.java (POJOs)
// Java gRPC server (Spring Boot with grpc-spring-boot-starter):
@GrpcService
public class UserGrpcService extends UserServiceGrpc.UserServiceImplBase {
@Override
public void getUser(GetUserRequest req, StreamObserver<UserResponse> observer) {
UserResponse response = UserResponse.newBuilder()
.setId(req.getUserId())
.setName("Alice")
.setEmail("alice@example.com")
.build();
observer.onNext(response);
observer.onCompleted();
}
}gRPC vs REST Comparison
Choosing between gRPC and REST depends on the consumer (browser vs service), need for streaming, and team tooling. Many organisations use both: REST for public APIs, gRPC for internal microservice communication.
// gRPC vs REST comparison:
// ┌─────────────────────┬──────────────────────┬──────────────────────┐
// │ Property │ REST + JSON │ gRPC + Protobuf │
// ├─────────────────────┼──────────────────────┼──────────────────────┤
// │ Protocol │ HTTP/1.1 or HTTP/2 │ HTTP/2 required │
// │ Payload format │ JSON (text) │ Protobuf (binary) │
// │ Payload size │ Larger │ 5–10× smaller │
// │ Performance │ Baseline │ ~5–10× faster │
// │ Streaming │ No (SSE workaround) │ Yes (4 modes) │
// │ Type safety │ No schema (OpenAPI) │ Strict .proto schema │
// │ Browser support │ Native │ gRPC-Web proxy needed│
// │ Debugging │ Easy (curl, Postman) │ Hard (binary) │
// │ Code generation │ Optional (OpenAPI) │ Required (protoc) │
// │ Best for │ Public APIs, browser │ Internal services │
// └─────────────────────┴──────────────────────┴──────────────────────┘
// Java gRPC client (blocking stub):
ManagedChannel channel = ManagedChannelBuilder
.forAddress("user-service", 9090)
.usePlaintext() // use .useTransportSecurity() in prod
.build();
UserServiceGrpc.UserServiceBlockingStub stub = UserServiceGrpc.newBlockingStub(channel);
UserResponse user = stub.getUser(
GetUserRequest.newBuilder().setUserId("u-123").build()
);
System.out.println(user.getName()); // type-safe — no JSON parsingKey Points to Remember
- 1gRPC uses HTTP/2 + Protobuf; REST typically uses HTTP/1.1 + JSON.
- 2Protobuf payloads are 5–10× smaller and faster to serialise than JSON.
- 3gRPC supports 4 patterns: unary, server streaming, client streaming, bidirectional.
- 4gRPC requires HTTP/2 — complicates some load balancer and proxy setups.
- 5Browsers cannot use gRPC natively — require gRPC-Web proxy (Envoy).
- 6Common pattern: REST for public APIs, gRPC for internal microservice-to-microservice calls.
Interview Questions
Sign in to ask AriaWhat are the main differences between gRPC and REST?
Why does gRPC require HTTP/2?
What are the four communication patterns supported by gRPC?
When would you choose gRPC over REST for microservice communication?
How would you expose a gRPC service to a browser-based frontend?
Ask Aria about gRPC vs REST
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.