gRPC telah menjadi salah satu protokol komunikasi yang paling banyak digunakan di ekosistem aplikasi mikroservis modern. Fungsi utamanya sebagai pengganti REST di banyak sistem tidak lepas dari fleksibilitas model RPC (Remote Procedure Call), kecepatan, serta kemampuan streaming datanya yang superior. Salah satu model streaming yang cukup powerful adalah Server-side Streaming RPC.
Pada artikel ini, saya akan membahas konsep Server-side Streaming RPC, langkah implementasinya, serta studi kasus menggunakan bahasa Go (golang
). Untuk memudahkan pemahaman, akan ada contoh kode, simulasi alur request-response, dan tabel perbandingan sederhana antara model RPC lainnya.
Apa Itu Server-side Streaming RPC?
Pada skenario Server-side Streaming RPC, klien mengirimkan satu permintaan ke server dan menerima stream respons secara bertahap dari server hingga selesai. Intinya, server dapat mengirim lebih dari satu pesan kembali ke klien setelah permintaan awal diterima—mirip seperti “push notification” di jalur HTTP/2.
Diagram Alur
Mari kita visualisasikan alurnya menggunakan mermaid diagram:
sequenceDiagram participant Client participant Server Client->>Server: Send Request (permintaan tunggal) loop Selama masih ada data Server-->>Client: Stream Response (berulang kali) end Server-->>Client: (Stream selesai / EOF)
Kapan Menggunakan Server-side Streaming RPC?
Beberapa use case khas meliputi:
- Pengiriman data dalam batch besar (report, file, logs)
- Streaming hasil query database secara bertahap
- Push notifikasi tentang status atau update proses latar belakang
- Event-driven communication (misal: progres build pipeline)
Tabel berikut membandingkan model RPC dalam gRPC:
Jenis RPC | Request | Response | Contoh |
---|---|---|---|
Unary RPC | Satu | Satu | GetUser() -> User |
Server-side Streaming | Satu | Stream (banyak) | ListLogs() -> LogEntry* |
Client-side Streaming | Stream (banyak) | Satu | UploadPhotos() -> UploadStatus |
Bidirectional Streaming | Stream | Stream (banyak, 2 arah) | Chat() -> Message* /Message* |
Studi Kasus: Streaming Log dengan gRPC Go
Kita akan membuat service gRPC sederhana bernama LogService
, di mana klien dapat meminta log dan server akan membalas dengan stream data log secara bertahap.
1. Mendefinisikan Protobuf
File: log.proto
syntax = "proto3";
package log;
service LogService {
rpc FetchLogs(LogRequest) returns (stream LogEntry) {}
}
message LogRequest {
string filter = 1;
}
message LogEntry {
int32 id = 1;
string timestamp = 2;
string message = 3;
}
2. Implementasi Server
File: server.go
package main
import (
"context"
"fmt"
"log"
"net"
"time"
"google.golang.org/grpc"
pb "path/to/your/generated/proto/log"
)
type server struct {
pb.UnimplementedLogServiceServer
}
func (s *server) FetchLogs(req *pb.LogRequest, stream pb.LogService_FetchLogsServer) error {
logs := []pb.LogEntry{
{Id: 1, Timestamp: "2024-06-05T10:00:00Z", Message: "Server started"},
{Id: 2, Timestamp: "2024-06-05T10:10:00Z", Message: "Process completed"},
{Id: 3, Timestamp: "2024-06-05T10:15:00Z", Message: "User login"},
}
for _, entry := range logs {
// Simulasi log dikirim bertahap
if err := stream.Send(&entry); err != nil {
return err
}
time.Sleep(1 * time.Second) // Simulasi delay streaming
}
return nil
}
func main() {
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterLogServiceServer(s, &server{})
log.Println("gRPC server started at :50051")
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
3. Implementasi Client
File: client.go
package main
import (
"context"
"log"
"time"
"google.golang.org/grpc"
pb "path/to/your/generated/proto/log"
)
func main() {
conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
c := pb.NewLogServiceClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
stream, err := c.FetchLogs(ctx, &pb.LogRequest{Filter: "all"})
if err != nil {
log.Fatalf("Error on FetchLogs: %v", err)
}
for {
entry, err := stream.Recv()
if err != nil {
log.Printf("End of stream or error: %v", err)
break
}
log.Printf("LogEntry: [%d] %s - %s", entry.Id, entry.Timestamp, entry.Message)
}
}
4. Simulasi Interaksi Klien-Server
Mari gambarkan simulasi request dan response:
sequenceDiagram participant Client participant Server Client->>Server: FetchLogs({filter:"all"}) Server-->>Client: LogEntry #1 Note over Server,Client: (1 detik kemudian) Server-->>Client: LogEntry #2 Note over Server,Client: (1 detik kemudian) Server-->>Client: LogEntry #3 Server-->>Client: [EOF]
Tantangan dan Praktik Terbaik
1. Error Handling:
Stream bisa putus akibat jaringan atau error aplikasi. Pastikan error propagation jelas di kedua sisi; gunakan kode status gRPC (codes.Canceled
, codes.Unavailable
, dll).
2. Deadline/Timeout:
Klien wajib memberikan deadline agar stream tak menggantung selamanya.
3. Skalabilitas:
Streaming cocok untuk volume data besar, tapi tetaplah perhatikan batasan buffer, pool goroutine, dan pengaturan flow-control.
4. Versioning:
Jagalah backward-compatibility pada pesan stream, terutama jika ada klien/services lintas versi.
Kesimpulan
Server-side Streaming RPC adalah fitur powerful dari gRPC yang cocok untuk mengirimkan data dalam jumlah banyak atau bila respon tidak bisa sekaligus dikirim (misal, progres report, hasil query besar, notifikasi update, dsb).
Dengan memahami pola implementasi server-side streaming, engineer dapat:
- Menghemat resource (karena data tak ditahan sebagai satu batch besar)
- Meningkatkan responsifitas klien (data bisa segera diproses setelah diterima sebagian)
- Memanfaatkan jalur komunikasi di HTTP/2 lebih optimal
Jika Anda ingin lebih siap menghadapi kebutuhan real-time atau big-data di backend sistem mikroservis Anda, server-side streaming adalah skill yang wajib dikuasai.
Referensi:
Jika artikel ini bermanfaat, jangan lupa share dan beri bintang!
Mari diskusi: implementasi streaming RPC seperti apa yang pernah kamu lakukan—dan apa tantangannya? Tulis di kolom komentar! 🚀
21 Memahami Konsep Streaming pada gRPC
Artikel Terhangat
22 Implementasi Server-side Streaming RPC
06 Jun 2025
21 Memahami Konsep Streaming pada gRPC
06 Jun 2025
20 Menambahkan Interceptor Unary di Client
06 Jun 2025
19 Menambahkan Interceptor Unary di Server
06 Jun 2025
18 Membaca Metadata di Server gRPC
06 Jun 2025
17 Menambahkan Metadata pada gRPC Request
06 Jun 2025
16 Penanganan Error di Server gRPC
06 Jun 2025

22 Implementasi Server-side Streaming RPC

21 Memahami Konsep Streaming pada gRPC

20 Menambahkan Interceptor Unary di Client

19 Menambahkan Interceptor Unary di Server

18 Membaca Metadata di Server gRPC

17 Menambahkan Metadata pada gRPC Request
