REST vs gRPC vs GraphQL ā A Complete Guide With Java Examples
APIs power every modern application ā mobile apps, microservices, dashboards, IoT devices, and more. And today, developers have three major API technologies to choose from:
- REST (HTTP/JSON)
- gRPC (HTTP/2 + Protocol Buffers)
- GraphQL (single endpoint + flexible queries)
Each has its strengths, weaknesses, and ideal use cases.
š 1. REST ā The Traditional Standard
REST is the most widely used API style, built around:
- Resources (
/users,/orders) - HTTP verbs (
GET,POST,PUT,DELETE) - JSON as the default format
ā Strengths
- Easy to understand
- Browser-friendly
- Great tooling
- Good for public APIs
ā Weaknesses
- Over-fetching
- Under-fetching
- JSON overhead
- HTTP/1.1 latency
Java Example
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping("/{id}")
public User getUser(@PathVariable int id) {
return new User(id, "John Doe");
}
}
ā” 2. gRPC ā High-Performance, Low-Latency APIs
gRPC uses:
- HTTP/2
- Protocol Buffers
- Generated client/server code
- Streaming
ā Strengths
- Extremely fast
- Small binary payloads
- Streaming support
- Strong typing
ā Weaknesses
- Not browser-native
- Harder to debug binary payloads
gRPC Java Example
user.proto:
syntax = "proto3";
service UserService {
rpc GetUser(GetUserRequest) returns (GetUserResponse);
}
message GetUserRequest {
int32 id = 1;
}
message GetUserResponse {
int32 id = 1;
string name = 2;
}
Server:
public class UserServiceImpl extends UserServiceGrpc.UserServiceImplBase {
@Override
public void getUser(GetUserRequest request, StreamObserver<GetUserResponse> responseObserver) {
GetUserResponse response = GetUserResponse.newBuilder()
.setId(request.getId())
.setName("John Doe")
.build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
š 3. GraphQL ā Flexible Queries for Frontend Apps
GraphQL allows clients to request exactly the data they need.
ā Strengths
- Avoids over-fetching
- Strong schema
- Great for mobile & dashboards
ā Weaknesses
- Harder caching
- Over-fetching risks in resolvers
- Performance overhead in large graphs
Java Example (Spring GraphQL)
Schema:
type User {
id: Int
name: String
}
type Query {
user(id: Int!): User
}
Resolver:
@Component
public class UserQueryResolver implements GraphQLQueryResolver {
public User user(int id) {
return new User(id, "John Doe");
}
}
š Performance Comparison
| Feature | REST | gRPC | GraphQL |
|---|---|---|---|
| Transport | HTTP/1.1 | HTTP/2 | HTTP/1.1 |
| Format | JSON | ProtoBuf (binary) | JSON |
| Speed | Medium | Fastest | Medium |
| Streaming | ā No | ā Yes | ā Partial |
| Browser support | ā Excellent | ā Needs gRPC-Web | ā Excellent |
| Typing | Weak | Strong | Strong |
| Ideal for | Public APIs | Microservices | Frontend apps |
šÆ When to Choose What?
ā Use REST when:
- Building public APIs
- Browser-based clients
- Simplicity matters
ā Use gRPC when:
- You need performance
- Microservices communicate internally
- You need streaming
ā Use GraphQL when:
- Frontend needs flexible queries
- You want to avoid over-fetching
- Mobile apps require optimized data loads
š§ Final Summary
- REST ā Simple, universal
- gRPC ā Fast, efficient, best for microservices
- GraphQL ā Flexible, client-driven
Each excels in different scenarios.