gRPC for Inter-Service Communication
AdvancedgRPC uses Protocol Buffers for efficient binary serialisation and HTTP/2 for multiplexed streams; ideal for high-throughput internal service calls where JSON overhead matters.
Overview
gRPC is a high-performance RPC framework from Google that uses Protocol Buffers (protobuf) for binary serialisation and HTTP/2 for transport. Compared to REST+JSON, gRPC reduces payload size by 60–80%, uses multiplexed streams (multiple requests on one TCP connection), and enforces a strong schema contract through .proto files. Clients and servers in any supported language are generated from the same .proto definition, eliminating client SDK drift. gRPC supports four communication patterns: unary (request-response), server streaming, client streaming, and bidirectional streaming. In Spring Boot, the grpc-spring-boot-starter library wires gRPC servers and stubs into the Spring context with full interceptor and security support.
Defining a service in .proto and generating Java stubs
Protocol Buffer definitions are the source of truth. The protoc compiler + grpc-java plugin generates service base classes and client stubs.
// order_service.proto
syntax = "proto3";
package com.example.grpc;
option java_multiple_files = true;
service OrderService {
rpc CreateOrder (CreateOrderRequest) returns (OrderResponse);
rpc GetOrder (GetOrderRequest) returns (OrderResponse);
rpc StreamOrders (StreamOrdersRequest) returns (stream OrderResponse);
}
message CreateOrderRequest {
string customer_id = 1;
double amount = 2;
repeated OrderItem items = 3;
}
message OrderItem {
string product_id = 1;
int32 quantity = 2;
}
message OrderResponse {
string order_id = 1;
string status = 2;
}
message GetOrderRequest { string order_id = 1; }
message StreamOrdersRequest { string customer_id = 1; }
# pom.xml
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-server-spring-boot-starter</artifactId>
<version>3.1.0.RELEASE</version>
</dependency>gRPC server implementation in Spring Boot
Extend the generated service base class and annotate with @GrpcService. Spring Boot auto-starts the gRPC server on port 9090.
@GrpcService
public class OrderGrpcService extends OrderServiceGrpc.OrderServiceImplBase {
@Autowired
private OrderRepository orderRepository;
@Override
public void createOrder(CreateOrderRequest req,
StreamObserver<OrderResponse> responseObserver) {
try {
Order order = new Order(req.getCustomerId(), req.getAmount());
orderRepository.save(order);
OrderResponse response = OrderResponse.newBuilder()
.setOrderId(order.getId().toString())
.setStatus("CREATED")
.build();
responseObserver.onNext(response);
responseObserver.onCompleted();
} catch (Exception e) {
responseObserver.onError(Status.INTERNAL
.withDescription(e.getMessage())
.asRuntimeException());
}
}
@Override
public void streamOrders(StreamOrdersRequest req,
StreamObserver<OrderResponse> responseObserver) {
orderRepository.findByCustomerId(req.getCustomerId())
.forEach(order -> responseObserver.onNext(toResponse(order)));
responseObserver.onCompleted(); // close stream
}
}gRPC client stub in another service
The grpc-client-spring-boot-starter injects a stub automatically. Blocking stubs for synchronous calls; async stubs for reactive or non-blocking patterns.
# application.properties — client config
grpc.client.order-service.address=static://order-service:9090
grpc.client.order-service.negotiationType=PLAINTEXT # or TLS
// gRPC client in a consuming service
@Service
public class CheckoutService {
@GrpcClient("order-service")
private OrderServiceGrpc.OrderServiceBlockingStub orderStub;
public String createOrder(CheckoutRequest req) {
CreateOrderRequest grpcReq = CreateOrderRequest.newBuilder()
.setCustomerId(req.getCustomerId())
.setAmount(req.getTotal())
.build();
try {
OrderResponse response = orderStub
.withDeadlineAfter(2, TimeUnit.SECONDS) // always set deadline!
.createOrder(grpcReq);
return response.getOrderId();
} catch (StatusRuntimeException e) {
if (e.getStatus().getCode() == Status.Code.UNAVAILABLE) {
throw new ServiceUnavailableException("Order service down");
}
throw e;
}
}
}Key Points to Remember
- 1gRPC uses HTTP/2 for multiplexed connections — multiple simultaneous RPCs over one TCP socket, unlike HTTP/1.1.
- 2Protobuf binary encoding is ~5–10× smaller than JSON for the same data and significantly faster to serialise/deserialise.
- 3Always set withDeadlineAfter() on client stubs — gRPC does not have default timeouts.
- 4gRPC status codes (UNAVAILABLE, DEADLINE_EXCEEDED, NOT_FOUND) map to HTTP status codes differently; handle them explicitly.
- 5gRPC-Web is required for browser clients; native gRPC cannot be called directly from browsers due to HTTP/2 trailers.
- 6Use server streaming for pushing large result sets; bidirectional streaming for real-time collaborative features.
Interview Questions
Sign in to ask AriaWhat advantages does gRPC have over REST+JSON for internal microservice communication?
Explain the four gRPC communication patterns and when you would use each.
How does gRPC handle backward compatibility when you change a .proto definition?
What happens if a gRPC client calls a server that does not set a deadline?
How would you add authentication to gRPC calls in a Spring Boot microservice?
Ask Aria about gRPC for Inter-Service Communication
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.