Jika Anda sudah familiar dengan REST API, mungkin konsep komunikasi request-response terasa sangat natural. Namun, saat aplikasi makin kompleks dan kebutuhan komunikasi dua arah yang efisien dibutuhkan—seperti real-time chat, monitoring sistem, atau transfer file yang besar—REST mulai menunjukkan keterbatasannya. Di sinilah kekuatan gRPC, khususnya fitur streaming-nya, benar-benar menonjol.
Pada artikel kali ini, kita akan membedah konsep streaming pada gRPC. Kita akan memahami mekanismenya, melihat tipe-tipe streaming pada gRPC, dan menuliskannya dalam contoh kode Go yang mudah dicerna. Tidak lupa, kita juga menyajikan simulasi, diagram alur, dan tabel supaya konsepnya makin solid di kepala.
Apa Itu Streaming pada gRPC?
Secara sederhana, streaming pada gRPC adalah mekanisme di mana klien dan/atau server dapat mengirimkan serangkaian pesan, bukan hanya satu request/response saja. Artinya, data dapat ‘dikirim bertahap’ antar klien dan server, secara asynchronous maupun synchronous, tanpa harus menunggu semua data selesai di sisi pengirim.
Mengapa Streaming Perlu?
Beberapa use-case yang paling membutuhkan streaming:
- File transfer besar: Memecah file besar menjadi chunk yang dikirim bertahap.
- Real-time chat: Pesan bisa terus mengalir dua arah.
- Live data feed: Streaming monitor server, dashboard transaksi, dsb.
Tipe-Tipe Streaming pada gRPC
Ada empat jenis metode RPC di gRPC:
Tipe | Client Stream | Server Stream | Contoh Skenario |
---|---|---|---|
Unary | ❌ | ❌ | Request-Response |
Server Streaming | ❌ | ✅ | Monitor server |
Client Streaming | ✅ | ❌ | Upload file chunk |
Bidirectional | ✅ | ✅ | Live chat |
Mari kita lihat diagram mermaid berikut untuk visualisasinya:
flowchart LR A[Unary] --> B1[Client Request] & B2[Server Response] C[Server Streaming] --> D1[Client Request] --> D2[Server Stream Data] E[Client Streaming] --> F1[Client Stream Data] --> F2[Server Response] G[Bidirectional] --> H1[Client Stream] <--> H2[Server Stream]
1. Unary RPC (Request-Response)
Paling sederhana, satu permintaan dibalas satu respons. Tidak ada streaming. Biasanya seperti ini di Protobuf:
service FileService {
rpc GetFileMetadata(FileRequest) returns (FileMetadata) {}
}
2. Server Streaming RPC
Klien mengirim satu request, server membalas serangkaian data stream. Contoh kasus: dashboard yang ingin menampilkan update status server secara periodik.
service MonitorService {
rpc MonitorStatus(Empty) returns (stream Status) {}
}
Alurnya:
- Client kirim request.
- Server kirim berkali-kali data/response hingga selesai.
- Client membaca stream data sampai habis.
Contoh kode Go (Server Streaming)
Definisi Protobuf:
syntax = "proto3";
service MonitorService {
rpc MonitorStatus(Empty) returns (stream Status) {}
}
message Status {
string server = 1;
string state = 2;
int32 cpuUsage = 3;
}
message Empty {}
Server Go:
func (s *server) MonitorStatus(req *Empty, stream MonitorService_MonitorStatusServer) error {
for i := 0; i < 5; i++ {
status := &Status{
Server: "MyApp",
State: "UP",
CpuUsage: rand.Int31n(100),
}
if err := stream.Send(status); err != nil {
return err
}
time.Sleep(2 * time.Second)
}
return nil
}
Client Go:
stream, _ := client.MonitorStatus(context.Background(), &Empty{})
for {
status, err := stream.Recv()
if err == io.EOF {
break
}
fmt.Printf("Status: %+v\n", status)
}
3. Client Streaming RPC
Client dapat mengirim banyak pesan ke server, lalu server membalas satu kali response setelah semua pesan diterima.
Use-case: Mengirim bagian-bagian file (chunk) untuk diunggah.
Protobuf:
service FileService {
rpc Upload(stream FileChunk) returns (UploadStatus) {}
}
message FileChunk {
bytes content = 1;
}
message UploadStatus {
string message = 1;
}
Server Go:
func (s *server) Upload(stream FileService_UploadServer) error {
var totalBytes int
for {
chunk, err := stream.Recv()
if err == io.EOF {
return stream.SendAndClose(&UploadStatus{Message: fmt.Sprintf("Received %d bytes", totalBytes)})
}
totalBytes += len(chunk.Content)
}
}
Client Go:
stream, _ := client.Upload(context.Background())
for i := 0; i < 10; i++ {
stream.Send(&FileChunk{Content: []byte("part")})
}
resp, _ := stream.CloseAndRecv()
fmt.Println(resp.Message)
4. Bidirectional Streaming
Baik client maupun server dapat saling mengirim data stream kapan saja dan seberapa banyak.
Use-case: Real-time chat, collaborative editing, dsb.
Protobuf:
service ChatService {
rpc Chat(stream ChatMessage) returns (stream ChatMessage) {}
}
message ChatMessage {
string user = 1;
string text = 2;
int64 timestamp = 3;
}
Server Go:
func (s *server) Chat(stream ChatService_ChatServer) error {
for {
msg, err := stream.Recv()
if err == io.EOF {
return nil
}
// broadcast to other users (simplified)
stream.Send(&ChatMessage{
User: "Server",
Text: "Received: " + msg.Text,
Timestamp: time.Now().Unix(),
})
}
}
Client Go:
ctx := context.Background()
stream, _ := client.Chat(ctx)
go func() {
for _, text := range []string{"Hi", "Apa kabar?"} {
stream.Send(&ChatMessage{User: "Alice", Text: text, Timestamp: time.Now().Unix()})
time.Sleep(time.Second)
}
stream.CloseSend()
}()
for {
msg, err := stream.Recv()
if err == io.EOF {
break
}
fmt.Printf("Received: %s\n", msg.Text)
}
Simulasi Waktu & Efisiensi
Mari bandingkan upload file 100MB
dengan RPC unary vs client streaming:
Metode | Chunk Size | Total Request | Latency per Req | Est. Total Time |
---|---|---|---|---|
Unary (100MB sekali) | - | 1 | 5s | 5s |
Streaming (10MB) | 10MB | 10 | 0.5s | 5s |
Streaming pipeline | 10MB | 10 | parallel (0.5s) | ~0.5s |
Pada streaming, chunk dapat dikirim bertahap & pipeline, sehingga selama bandwidth cukup, waktu lebih cepat dan resource lebih optimal.
Kesimpulan
gRPC Streaming membuka peluang komunikasi jaringan yang jauh lebih fleksibel, efisien, dan real-time dibandingkan RPC konvensional (unary). Berikut key takeaway-nya:
- Gunakan server streaming untuk broadcast/monitoring.
- Pilih client streaming untuk upload banyak data secara bertahap.
- Manfaatkan bidirectional streaming untuk use-case dua arah real-time.
- Streaming lebih efisien untuk data besar/berulang ketimbang unary.
Teknologi ini akan makin krusial seiring bergesernya aplikasi ke arah interaktif, event-driven, dan data intensif.
Semoga penjelasan, kode, dan diagram di atas bikin Anda makin mantap memahami streaming di gRPC. Sudah siap mengimplementasikannya ke sistem produksi Anda? 🚀
20 Menambahkan Interceptor Unary di Client
Artikel Terhangat
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

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
