gRPC in Java: When to Use and How to Choose Wisely

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Is REST Dead? No, You Just Have a Choice Now

\n\n

Every Java developer has written a REST API at least once. It's convenient, familiar, and JSON is human-readable. But when load increases and latency becomes critical, REST starts to creak. And that's when gRPC enters the stage — a technology from Google that promises speed comparable to a local call, serialization speed 10 times faster than JSON, and built-in streaming support.

\n\n

In this article, we'll figure out when gRPC in Java is truly justified and when it's better to stick with REST. No fluff — only real scenarios, code examples, and honest benchmarks.

\n\n

What is gRPC and Why Is Everyone Talking About It?

\n\n

gRPC is a framework for remote procedure calls (RPC). Instead of JSON, it uses Protocol Buffers (protobuf) — a binary serialization format. Instead of HTTP/1.1 — HTTP/2 with multiplexing and header compression.

\n\n

For Java, this means:

\n
    \n
  • Strictly typed contracts via .proto files
  • \n
  • Automatic generation of clients and servers
  • \n
  • Four types of interaction: unary, server streaming, client streaming, bidirectional streaming
  • \n
  • Built-in support for timeouts, deadlines, and load balancing
  • \n
\n\n

What Does a Typical .proto File Look Like?

\n\n
syntax = "proto3";\n\npackage com.pythonlib.example;\n\nservice UserService {\n    rpc GetUser (UserRequest) returns (UserResponse);\n    rpc ListUsers (UserListRequest) returns (stream UserResponse);\n    rpc UpdateUser (stream UserUpdateRequest) returns (UserResponse);\n    rpc Chat (stream ChatMessage) returns (stream ChatMessage);\n}\n\nmessage UserRequest {\n    int32 id = 1;\n}\n\nmessage UserResponse {\n    int32 id = 1;\n    string name = 2;\n    string email = 3;\n}\n\nmessage UserListRequest {\n    int32 page = 1;\n    int32 size = 2;\n}\n\nmessage UserUpdateRequest {\n    int32 id = 1;\n    string name = 2;\n}\n\nmessage ChatMessage {\n    string user = 1;\n    string text = 2;\n}\n
\n\n

After compilation with protoc, you'll get a ready-made Java class with builders — no manual mappers required.

\n\n

When is gRPC in Java the Best Choice? 5 Scenarios

\n\n

1. High-Load Microservices

\n\n

If you have 50+ microservices communicating thousands of times per second, gRPC reduces latency by 30-50% compared to REST. Protobuf takes up less space, and HTTP/2 allows keeping a single connection for all requests.

\n\n

Real-world example: We migrated an internal recommendation service from REST to gRPC. Response time dropped from 12 ms to 4 ms, and traffic was reduced by 3 times.

\n\n

2. Real-Time Data Streaming

\n\n

gRPC natively supports server-side streaming, client-side streaming, and bidirectional streaming. This is ideal for:

\n
    \n
  • Logs and metrics (agent sends a stream of data)
  • \n
  • Chat systems and notifications
  • \n
  • Processing large files in chunks
  • \n
\n\n

Server implementation with server streaming in Java:

\n\n
import io.grpc.stub.StreamObserver;\n\npublic class UserServiceImpl extends UserServiceGrpc.UserServiceImplBase {\n\n    @Override\n    public void listUsers(UserListRequest request,\n                          StreamObserver<UserResponse> responseObserver) {\n        for (int i = 0; i < 10; i++) {\n            UserResponse user = UserResponse.newBuilder()\n                    .setId(i)\n                    .setName("User_" + i)\n                    .setEmail("user" + i + "@pythonlib.ru")\n                    .build();\n            responseObserver.onNext(user);\n            try {\n                Thread.sleep(200); // simulate delay\n            } catch (InterruptedException e) {\n                responseObserver.onError(e);\n            }\n        }\                

Blogs

Book Recommendations