HTTP, REST, gRPC Protocols
Protocol choice matches client capabilities with the system's performance, contract, and operational needs. If changing the protocol does not simplify the architecture, designing the existing protocol well is usually cheaper.
Quick Decision
| Need | Prefer | Watch Out |
|---|---|---|
| Public web/mobile API | HTTP/REST | Error model and versioning must be consistent |
| Low-latency internal service calls | gRPC | Protobuf contract and tooling are required |
| Real-time bidirectional channel | WebSocket | Connection management and scaling get harder |
| One-way live updates | Server-Sent Events | Simple, but not fit for every scenario |
Production Checklist
- Problem: Which bottleneck does the protocol solve: latency, payload, streaming, contract, or client diversity?
- Solution: Are timeout, retry, idempotency, auth, and observability standards defined per protocol?
- Trade-off: REST gives debugging simplicity; gRPC gives performance; WebSocket adds state management.
- Failure mode: Deadline exceeded, connection reset, partial response, and retry storm scenarios should be handled.
- Measurement: Track payload size, round-trip count, connection count, p95 latency, and error code distribution.
- Security/cost: TLS, mTLS, schema validation, and rate-limit needs vary by protocol.
Protocol Interaction
REST API Lifecycle
gRPC Stream Types
REST API Development with Spring Boot
Spring WebMVC
- Traditional servlet-based approach
- Blocking I/O model
- Widely adopted and mature
Spring WebFlux
- Reactive programming model
- Non-blocking I/O
- Mono/Flux types for async streams
Content Negotiation
@RequestMapping(produces/consumes)for MediaType handling- JSON/XML/Protocol Buffers support
Validation
- Bean Validation (
@Valid,@NotNull,@Size) for request validation - MethodValidationInterceptor for method-level validation
Error Handling
@ControllerAdvicefor global exception handling- ResponseEntity for custom HTTP status codes
REST API Best Practices (with Spring Boot)
Richardson Maturity Model
- Level 0: HTTP as transport
- Level 1: Resources
- Level 2: HTTP Verbs
- Level 3: HATEOAS support with Spring HATEOAS library
Versioning Strategies
- URL versioning (
/api/v1/) - Header-based versioning
- Content negotiation
Documentation
- SpringDoc OpenAPI (Swagger) for automatic API documentation
@Operationand@Schemaannotations
Security
- Spring Security for JWT token validation
- OAuth2 Resource Server configuration
gRPC Integration (with Spring Boot)
gRPC Starters
spring-boot-starter-grpc-server/clientdependencies
Protobuf Code Generation
protobuf-maven-pluginfor Java class generation
Service Implementation
@GrpcServiceannotation for service implementation- Blocking/non-blocking stubs
Interceptors
- gRPC interceptors for authentication, logging, metrics collection
Performance Benefits
- 30-50% less bandwidth with binary serialization
- HTTP/2 multiplexing
- Bi-directional streaming
Protocol Selection Criteria
REST
- ✅ Public APIs
- ✅ Browser-based clients
- ✅ Human-readable requirements
- ✅ Caching support
- ❌ High-performance scenarios
gRPC
- ✅ High-performance internal services
- ✅ Polyglot microservices
- ✅ Real-time streaming requirements
- ✅ Type safety
- ❌ Browser support
GraphQL
- ✅ Complex query requirements
- ✅ Mobile clients with bandwidth optimization
- ✅ Frontend-driven development
- ❌ Caching complexity
GraphQL Integration
Spring GraphQL
- Schema-first approach
- Type definitions
DataFetcher
- Custom resolver implementations
- N+1 problem solution
Batching & Caching
- DataLoader pattern
- Field-level caching
Security
- Field-level authorization
- Depth limiting
Performance Monitoring
- Query complexity analysis
- Execution time tracking
WebSocket & Server-Sent Events
Spring WebSocket
- STOMP protocol
- Message broker integration
Real-time Updates
- Pub/sub pattern
- Topic-based messaging
Connection Management
- Heartbeat mechanism
- Reconnection strategy
Scalability
- WebSocket clustering
- Sticky sessions
Security
- CSRF protection
- Origin validation
Protocol Comparison
| Feature | REST | gRPC | GraphQL |
|---|---|---|---|
| Performance | Medium | High | Medium |
| Browser Support | ✅ | ❌ | ✅ |
| Streaming | ❌ | ✅ | ✅ |
| Type Safety | ❌ | ✅ | ✅ |
| Caching | ✅ | ❌ | Complex |
| Learning Curve | Low | Medium | High |
Implementation Examples
REST Endpoint
@RestController
@RequestMapping("/api/v1/users")
public class UserController {
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
User user = userService.findById(id);
return ResponseEntity.ok(user);
}
@PostMapping
public ResponseEntity<User> createUser(@Valid @RequestBody CreateUserRequest request) {
User user = userService.create(request);
return ResponseEntity.status(CREATED).body(user);
}
}gRPC Service
@GrpcService
public class UserGrpcService extends UserServiceGrpc.UserServiceImplBase {
@Override
public void getUser(GetUserRequest request, StreamObserver<UserResponse> responseObserver) {
User user = userService.findById(request.getId());
UserResponse response = UserResponse.newBuilder()
.setUser(convertToProto(user))
.build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}Performance Optimization
REST API Optimization
- HTTP/2 support
- Response compression
- ETag caching
- Pagination
- Field selection
gRPC Optimization
- Connection pooling
- Streaming for large datasets
- Compression algorithms
- Keep-alive settings
Common Optimizations
- Request batching
- Connection reuse
- Circuit breaker pattern
- Load balancing
- Health checks
GraphQL Query Flow
WebSocket Connection Lifecycle
Performance Optimization Flow
Missing Protocol Details
REST Resource and Error Contract
REST endpoints should define resource identity, HTTP method, status code, and error body together. Use plural collections (/orders) and identified resources (/orders/{id}); GET should be safe, PUT and DELETE should be idempotent, and an idempotency key for POST must be part of the contract when needed.
Document 201 Created with Location, 202 Accepted with a job-status URL, 204 No Content, the 400/401/403/404/409/422 distinction, and 429 Retry-After behavior with examples. Error responses should carry a stable error code, field errors, request ID, and a safe message. See REST API Design for resource modeling, pagination, filtering, and HATEOAS.
Server-Sent Events Contract
SSE is a one-way, long-lived HTTP stream. The event format uses event, id, retry, and data fields:
event: order.updated
id: evt_123
retry: 5000
data: {"orderId":"ord_123","status":"ready"}The client sends Last-Event-ID after reconnect. State whether the server can resume from that ID or requires a full resync on a gap. Design heartbeat, proxy timeouts, connection limits, auth refresh, and backpressure together. Keep client commands in separate HTTP endpoints because SSE is server-to-client only.
gRPC Service Definition
The Protobuf service definition records RPC names, request/response types, and streaming direction:
service OrderService {
rpc GetOrder(GetOrderRequest) returns (Order);
rpc WatchOrders(WatchOrdersRequest) returns (stream OrderEvent);
rpc UploadEvents(stream OrderEvent) returns (UploadResult);
}Never reuse field numbers; mark removed fields as reserved. Define deadlines, status mapping, metadata auth, maximum message size, and retry policy. Test flow control, cancellation, and half-close behavior for bidirectional streams.
Use GraphQL API for schema and resolver details and API Contracts and Tooling for contracts, mocks, and generated clients.
