HTTP, REST, gRPC Protokolleri
Protokol seçimi, istemcinin yetenekleri ile sistemin performans, sözleşme ve operasyon ihtiyaçlarını eşleştirir. Protokol değişimi mimariyi sadeleştirmiyorsa, var olan protokolü iyi tasarlamak genellikle daha ucuzdur.
Hızlı Karar
| İhtiyaç | Tercih | Dikkat |
|---|---|---|
| Public web/mobile API | HTTP/REST | Hata modeli ve versiyonlama tutarlı olmalı |
| İç servisler arası düşük gecikme | gRPC | Protobuf sözleşmesi ve tooling gerekir |
| Gerçek zamanlı çift yönlü kanal | WebSocket | Bağlantı yönetimi ve ölçekleme zorlaşır |
| Tek yönlü canlı güncelleme | Server-Sent Events | Basit ama her senaryoya uymaz |
Üretim Kontrol Listesi
- Problem: Protokol hangi darboğazı çözüyor: latency, payload, streaming, sözleşme veya istemci çeşitliliği?
- Çözüm: Timeout, retry, idempotency, auth ve observability standardı protokol bazında tanımlı mı?
- Trade-off: REST debug kolaylığı sağlar; gRPC performans sağlar; WebSocket durum yönetimi ekler.
- Hata durumu: Deadline exceeded, connection reset, partial response ve retry storm senaryoları ele alınmalı.
- Ölçüm: Payload size, round-trip count, connection count, p95 latency ve error code dağılımı izlenmeli.
- Güvenlik/maliyet: TLS, mTLS, schema doğrulama ve rate limit gereksinimleri protokole göre değişir.
Protokol Etkileşimi
REST API Yaşam Döngüsü
gRPC Akış Tipleri
Spring Boot ile REST API Geliştirme
Spring WebMVC
- Geleneksel servlet tabanlı yaklaşım
- Bloklanabilir I/O modeli
- Yaygın olarak benimsenmiş ve olgun
Spring WebFlux
- Reaktif programlama modeli
- Bloklanmayan I/O
- Mono/Flux türleri ile eşzamansız akışlar
İçerik Müzakeresi
@RequestMapping(produces/consumes)ile MediaType işleme- JSON/XML/Protocol Buffers desteği
Doğrulama
- Bean Validation (
@Valid,@NotNull,@Size) ile istek doğrulama - MethodValidationInterceptor ile metod seviyesi doğrulama
Hata İşleme
@ControllerAdviceile global istisna işleme- ResponseEntity ile özel HTTP durum kodları
REST API En İyi Uygulamalar (Spring Boot ile)
Richardson Olgunluk Modeli
- Seviye 0: HTTP taşıma olarak
- Seviye 1: Kaynaklar
- Seviye 2: HTTP Fiilleri
- Seviye 3: HATEOAS desteği için Spring HATEOAS kütüphanesi
Sürümleme Stratejileri
- URL sürümlemesi (
/api/v1/) - Başlık tabanlı sürümleme
- İçerik müzakeresi
Dokümantasyon
- SpringDoc OpenAPI (Swagger) ile otomatik API dokümantasyonu
@Operationve@Schemaaçıklamaları
Güvenlik
- Spring Security ile JWT token doğrulama
- OAuth2 Resource Server yapılandırması
gRPC Entegrasyonu (Spring Boot ile)
gRPC Başlatıcıları
spring-boot-starter-grpc-server/clientbağımlılıkları
Protobuf Kod Üretimi
protobuf-maven-pluginile Java sınıf üretimi
Servis Uygulaması
@GrpcServiceaçıklaması ile servis uygulaması- Bloklanabilir/bloklanmayan taslaklar
Kesiciler
- gRPC kesicileri ile kimlik doğrulama, günlükleme, metrik toplama
Performans Faydaları
- İkili serileştirme ile %30-50 daha az bant genişliği
- HTTP/2 çoklama
- Çift yönlü akış
Protokol Seçim Kriterleri
REST
- ✅ Genel API'ler
- ✅ Tarayıcı tabanlı istemciler
- ✅ İnsan tarafından okunabilir gereksinimler
- ✅ Önbellek desteği
- ❌ Yüksek performans senaryoları
gRPC
- ✅ Yüksek performanslı dahili servisler
- ✅ Çok dilli mikroservisler
- ✅ Gerçek zamanlı akış gereksinimleri
- ✅ Tür güvenliği
- ❌ Tarayıcı desteği
GraphQL
- ✅ Karmaşık sorgu gereksinimleri
- ✅ Mobil istemciler ile bant genişliği optimizasyonu
- ✅ Ön uç odaklı geliştirme
- ❌ Önbellek karmaşıklığı
GraphQL Entegrasyonu
Spring GraphQL
- Şema öncelikli yaklaşım
- Tür tanımları
DataFetcher
- Özel çözümleyici uygulamaları
- N+1 problem çözümü
Toplu İşleme ve Önbellek
- DataLoader deseni
- Alan seviyesi önbellekleme
Güvenlik
- Alan seviyesi yetkilendirme
- Derinlik sınırlama
Performans İzleme
- Sorgu karmaşıklığı analizi
- Yürütme süresi takibi
WebSocket ve Sunucu Gönderilen Olaylar
Spring WebSocket
- STOMP protokolü
- Mesaj aracısı entegrasyonu
Gerçek Zamanlı Güncellemeler
- Yayın/abone deseni
- Konu tabanlı mesajlaşma
Bağlantı Yönetimi
- Kalp atışı mekanizması
- Yeniden bağlanma stratejisi
Ölçeklenebilirlik
- WebSocket kümeleme
- Yapışkan oturumlar
Güvenlik
- CSRF koruması
- Kaynak doğrulama
Protokol Karşılaştırması
| Özellik | REST | gRPC | GraphQL |
|---|---|---|---|
| Performans | Orta | Yüksek | Orta |
| Tarayıcı Desteği | ✅ | ❌ | ✅ |
| Akış | ❌ | ✅ | ✅ |
| Tür Güvenliği | ❌ | ✅ | ✅ |
| Önbellekleme | ✅ | ❌ | Karmaşık |
| Öğrenme Eğrisi | Düşük | Orta | Yüksek |
Uygulama Örnekleri
REST Uç Noktası
@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 Servisi
@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();
}
}Performans Optimizasyonu
REST API Optimizasyonu
- HTTP/2 desteği
- Yanıt sıkıştırma
- ETag önbellekleme
- Sayfalama
- Alan seçimi
gRPC Optimizasyonu
- Bağlantı havuzu
- Büyük veri kümeleri için akış
- Sıkıştırma algoritmaları
- Canlı tutma ayarları
Ortak Optimizasyonlar
- İstek toplu işleme
- Bağlantı yeniden kullanımı
- Devre kesici deseni
- Yük dengeleme
- Sağlık kontrolleri
GraphQL Sorgu Akışı
WebSocket Bağlantı Yaşam Döngüsü
Performans Optimizasyonu Akışı
Eksik Protokol Ayrıntıları
REST Kaynak ve Hata Sözleşmesi
REST endpoint'leri kaynak kimliği, HTTP metodu, durum kodu ve hata gövdesini birlikte tanımlamalıdır. Koleksiyonlar çoğul isimle (/orders), tek kaynaklar kimlikle (/orders/{id}) ifade edilir; GET güvenli, PUT ve DELETE idempotent davranışlı olmalı, POST için idempotency key gerekiyorsa sözleşmede yer almalıdır.
201 Created ile Location, 202 Accepted ile job status URL'si, 204 No Content, 400/401/403/404/409/422 ayrımı ve 429 Retry-After davranışı örneklerle belgelenmelidir. Hata response'u stable error code, field errors, request ID ve güvenli bir mesaj taşımalıdır. Ayrıntılı kaynak modelleme, pagination, filtering ve HATEOAS için REST API Tasarımı sayfasına bakılabilir.
Server-Sent Events Sözleşmesi
SSE tek yönlü, uzun ömürlü HTTP akışıdır. event, id, retry ve data alanları event formatını oluşturur:
event: order.updated
id: evt_123
retry: 5000
data: {"orderId":"ord_123","status":"ready"}Client reconnect sonrası Last-Event-ID gönderir; sunucu bu ID'den devam edebiliyor veya gap durumunda full resync istiyorsa bunu açıkça belirtmelidir. Heartbeat, proxy timeout, connection limit, authorization refresh ve backpressure birlikte tasarlanır. SSE yalnızca server-to-client olduğu için client command'ları ayrı HTTP endpoint'lerinde tutulur.
gRPC Service Definition
Protobuf servis tanımı RPC adını, request/response tipini ve streaming yönünü sözleşmeye alır:
service OrderService {
rpc GetOrder(GetOrderRequest) returns (Order);
rpc WatchOrders(WatchOrdersRequest) returns (stream OrderEvent);
rpc UploadEvents(stream OrderEvent) returns (UploadResult);
}Field number'ları yeniden kullanılmamalı, kaldırılan alanlar reserved yapılmalı ve deadline, status mapping, metadata auth, max message size ve retry policy tanımlanmalıdır. İki yönlü streaming için flow control, cancellation ve half-close davranışı ayrıca test edilmelidir.
GraphQL schema ve resolver ayrıntıları için GraphQL API; sözleşme, mock ve generated client süreci için API Contract ve Tooling sayfalarını kullan.
