REST — an architectural style using HTTP/1.1 or HTTP/2 with JSON for data exchange. gRPC — a high-performance RPC framework using HTTP/2 and Protocol Buffers (binary serialization).
System Design Context: REST dominates public APIs due to simplicity and tooling. gRPC excels in internal service-to-service communication where performance matters. Many modern architectures use both: gRPC internally, REST externally.
REST — Detailed Characteristics:
1// REST controller2@RestController3@RequestMapping("/api")4public class UserController {56 private final UserService userService;78 @GetMapping("/users/{id}")9 public ResponseEntity<UserDTO> getUser(@PathVariable Long id) {10 return userService.findById(id)11 .map(ResponseEntity::ok)12 .orElse(ResponseEntity.notFound().build());13 }1415 @GetMapping("/users")16 public ResponseEntity<Page<UserDTO>> listUsers(17 @RequestParam(defaultValue = "0") int page,18 @RequestParam(defaultValue = "20") int size) {19 return ResponseEntity.ok(userService.findAll(page, size));20 }21}
gRPC — Detailed Characteristics:
1// user_service.proto2syntax = "proto3";3package com.example;45service UserService {6 rpc GetUser (GetUserRequest) returns (User);7 rpc ListUsers (ListUsersRequest) returns (stream User);8 rpc CreateUser (CreateUserRequest) returns (User);9}1011message User {12 int64 id = 1;13 string name = 2;14 string email = 3;15}1617message GetUserRequest {18 int64 id = 1;19}2021message ListUsersRequest {22 int32 page_size = 1;23 string page_token = 2;24}
1// gRPC server implementation2@GrpcService3public class UserServiceImpl extends UserServiceGrpc.UserServiceImplBase {45 private final UserRepository userRepository;67 @Override8 public void getUser(GetUserRequest request,9 StreamObserver<User> responseObserver) {10 User user = userRepository.findById(request.getId())11 .map(this::toProto)12 .orElseThrow(() ->13 Status.NOT_FOUND14 .withDescription("User not found")15 .asRuntimeException());16 responseObserver.onNext(user);17 responseObserver.onCompleted();18 }1920 @Override21 public void listUsers(ListUsersRequest request,22 StreamObserver<User> responseObserver) {23 userRepository.findAll()24 .map(this::toProto)25 .forEach(responseObserver::onNext);26 responseObserver.onCompleted();27 }28}
Performance Comparison:
Common Pitfalls:
When to Use: