Episode ini membedah arsitektur gRPC dari dalam: bagaimana protobuf diubah menjadi kode client dan server, peran HTTP/2 multiplexing dan HPACK, komponen stub dan channel, serta metadata, deadline, dan status code yang mengatur setiap RPC.

Di episode 1 kalian tahu mengapa gRPC ada. Sekarang saatnya membuka kap mesin dan melihat bagaimana gRPC bekerja. Episode 2 membahas arsitektur inti: bagaimana satu file .proto menjadi kode client dan server, bagaimana HTTP/2 dipakai untuk multiplexing dan kompresi header, dan komponen runtime apa saja yang terlibat di setiap panggilan.
Pemahaman ini bukan sekadar teori. Ketika nanti menghadapi error seperti DeadlineExceeded atau latensi yang tidak wajar, kalian akan tahu bagian mana yang bermasalah — apakah di channel, di stub, di jaringan, atau di server. Mari mulai dari perjalanan sebuah kontrak.
Alur kerja gRPC berputar di sekitar compiler protoc. Kalian menulis kontrak di .proto, lalu protoc membangkitkan tiga hal: tipe message, antarmuka server, dan stub client. Karena semua bahasa membaca kontrak yang sama, tidak ada lagi ketidakcocokan antar tim.
syntax = "proto3";
package greet.v1;
message HelloRequest {
string name = 1;
}
message HelloResponse {
string message = 1;
}
service GreetService {
rpc SayHello(HelloRequest) returns (HelloResponse);
rpc Chat(HelloRequest) returns (stream HelloResponse);
}Perhatikan package greet.v1: namespace ini menentukan nama paket di kode hasil generate dan menjadi bagian dari nama method penuh, contohnya greet.v1.GreetService/SayHello.
Setelah code generation, setiap sisi mendapat dua artefak berbeda:
client.SayHello(ctx, req) dan stub yang menangani encoding, transport, dan decoding.Inilah model contract-driven development: antarmuka sudah dipaksa benar sebelum runtime berjalan.
gRPC memakai HTTP/2, bukan HTTP/1.1. Perbedaan terbesarnya adalah multiplexing: satu koneksi TCP bisa membawa banyak stream sekaligus, dan setiap stream bisa membawa banyak pesan. Jika REST membutuhkan satu koneksi per request, gRPC bisa menangani ribuan panggilan konkuren di satu koneksi.
Konsekuensinya penting: jangan membuka channel baru untuk setiap request. Satu channel gRPC harus di-reuse karena dia adalah kumpulan koneksi HTTP/2 yang sudah ada.
HTTP/2 juga memperkenalkan HPACK, kompresi header. Header seperti content-type dan grpc-status disimpan sebagai tabel; pengiriman berulang hanya mengirim indeks, bukan string penuh. Inilah salah satu alasan panggilan gRPC jauh lebih ringan daripada REST/JSON yang mengulang header di setiap request.
Karena koneksi dipertahankan, biaya handshake TCP dan TLS dibayar sekali, bukan per request. Untuk workload dengan banyak panggilan pendek, penghematan ini signifikan. Episode 10 akan membahas bagaimana mengelola siklus hidup koneksi ini secara eksplisit.
Channel adalah abstraksi koneksi ke sebuah alamat, misalnya localhost:50051. Channel menyimpan konfigurasi seperti pilihan TLS, keepalive, dan load balancing. Dalam kode Go, channel dibuat dengan grpc.NewClient atau grpc.DialContext:
import "google.golang.org/grpc"
conn, err := grpc.NewClient(
"localhost:50051",
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err != nil {
log.Fatal(err)
}
defer conn.Close()grpc.WithTransportCredentials(insecure.NewCredentials()) menandakan koneksi plaintext untuk pengembangan; pada episode 11 kalian akan menggantinya dengan kredensial TLS.
Data yang lewat adalah message protobuf. Runtime gRPC memakai codec untuk serialisasi dan deserialisasi: di sisi client, message di-encode menjadi biner sebelum dikirim; di sisi server, biner di-decode kembali menjadi objek bahasa. Protobuf juga memberi field numbering yang memungkinkan forward compatibility — topik episode 8.
Setiap RPC membawa metadata: pasangan key-value tambahan seperti token autentikasi, trace ID, atau region. Metadata dikirim sebagai header HTTP/2 dan bisa dibaca di kedua sisi. Episode 6 akan menggunakannya untuk auth dan logging.
Setiap panggilan gRPC sebaiknya punya deadline — batas waktu maksimal. Jika terlampaui, client menerima status DEADLINE_EXCEEDED dan RPC dibatalkan. Deadline mencegah request menggantung tanpa batas dan menjadi dasar pola timeout di episode 15.
gRPC memakai status code standar seperti OK, NOT_FOUND, INVALID_ARGUMENT, UNAUTHENTICATED, dan UNAVAILABLE. Status code dikirim bersama pesan error dan menjadi bahasa yang sama antara client dan server. Episode 5 membahas cara memetakan error domain ke status code yang tepat.
Inti yang harus dibawa pulang:
.proto menjadi kontrak tunggal yang membangkitkan stub client dan antarmuka server.Di episode 3 selanjutnya kalian akan langsung menulis API gRPC pertama dengan Protocol Buffers — struktur lengkap file .proto, tipe data v3 modern seperti enum, oneof, map, dan repeated, hingga cara mendeklarasikan keempat pola RPC: unary, server streaming, client streaming, dan bidirectional streaming. Siapkan editor kalian, karena mulai sekarang kita menulis kode nyata.