Episode ini mengajarkan menulis kontrak gRPC: struktur lengkap file .proto, tipe data protobuf v3 modern seperti enum, oneof, map, dan repeated, hingga cara mendeklarasikan empat pola RPC — unary, server streaming, client streaming, dan bidirectional.

Semua kehebatan gRPC bermuara pada satu file: .proto. File ini adalah kontrak yang dibaca manusia, compiler, client, dan server sekaligus. Di episode 3 kalian akan belajar menulis kontrak tersebut dengan benar — bukan sekadar contoh sederhana, tapi struktur yang siap untuk service nyata.
Kita akan membahas tiga lapisan kontrak: struktur file (package, imports, options), tipe data protobuf v3 (scalar, enum, oneof, map, repeated), dan definisi service dengan keempat pola RPC. Di akhir episode, kalian punya satu file .proto lengkap yang siap di-generate di episode 4.
Bagian paling atas file .proto berisi tiga deklarasi penting:
syntax = "proto3": memilih bahasa skema protobuf versi 3.package: namespace yang menentukan nama jenis di kode hasil generate, contohnya catalog.v1.import: menyertakan file lain, misalnya google/protobuf/timestamp.proto untuk tipe waktu.syntax = "proto3";
package catalog.v1;
import "google/protobuf/timestamp.proto";
option go_package = "learn-grpc/gen/catalog/v1;catalogv1";
message Product {
string id = 1;
string name = 2;
double price = 3;
}Option go_package menentukan lokasi output di Go; untuk bahasa lain, konvensinya berbeda-beda mengikuti plugin. Penulisan option go_package ini wajib untuk plugin Go.
Setiap field memakai nomor unik dalam satu message: string id = 1 berarti field bernomor 1. Nomor ini adalah bagian dari wire format, jadi jangan pernah mengubah makna nomor yang sudah dipakai. Nomor 1 sampai 15 memakai satu byte saja — berikan nomor kecil untuk field yang paling sering diakses.
Protobuf v3 menyediakan tipe scalar yang dipetakan ke tipe native bahasa: int32, int64, uint32, float, double, bool, string, dan bytes. Perhatikan bahwa semua field v3 bersifat optional: nilai default seperti 0 dan string kosong otomatis digunakan bila field tidak diisi.
Tiga konstruksi ini menyelesaikan sebagian besar masalah pemodelan data:
message Product {
enum Status {
STATUS_UNSPECIFIED = 0;
STATUS_ACTIVE = 1;
STATUS_ARCHIVED = 2;
}
Status status = 4;
oneof dimension {
int32 weight_grams = 5;
int32 volume_ml = 6;
}
map<string, string> attributes = 7;
}Product punya weight_grams atau volume_ml.color dan material.Untuk daftar nilai, gunakan repeated — setara list atau array di bahasa pemrograman:
message Order {
repeated string product_ids = 1;
int32 total = 2;
}repeated string product_ids = 1 bisa menyimpan nol atau banyak ID. Untuk tipe scalar, protobuf mengaktifkan packed encoding secara otomatis sehingga elemen list dikirim sangat ringkas.
Inti kontrak adalah blok service. Empat pola komunikasi didukung penuh oleh protobuf:
service ProductService {
rpc GetProduct(ProductId) returns (Product);
rpc ListProducts(ProductQuery) returns (stream Product);
rpc AddBulk(stream Product) returns (BulkResult);
rpc Search(stream SearchTerm) returns (stream Product);
}Baca deklarasi di atas: rpc GetProduct(ProductId) returns (Product) adalah unary, ListProducts memakai kata kunci stream di response, AddBulk memakai stream di request, dan Search memakai stream di keduanya.
Setiap method perlu tipe request dan response sendiri. Jangan memakai ulang message untuk tujuan berbeda — pasangan request-response yang terpisah memudahkan evoluasi skema tanpa saling merusak:
message ProductId {
string id = 1;
}
message ProductQuery {
string keyword = 1;
int32 limit = 2;
}
message BulkResult {
int32 added_count = 1;
}Beberapa praktik yang membuat kontrak kalian sehat dalam jangka panjang:
product_id) dan Pascal case untuk message (ProductQuery).STATUS_ACTIVE) agar kode hasil generate tidak ambigu.// di atas setiap field dan method sebagai dokumentasi otomatis.Kontrak yang rapi akan membuat kode hasil generate mudah dibaca oleh seluruh tim lintas bahasa.
Inti yang harus dibawa pulang:
.proto adalah kontrak tunggal yang dibaca manusia, compiler, client, dan server.package, import, dan option go_package membentuk kerangka file yang valid.stream pada posisi yang sesuai.Di episode 4 selanjutnya kalian akan membangkitkan kode dan menjalankan server-client pertama: instalasi plugin, perintah protoc untuk Go, implementasi server sederhana, implementasi client sederhana, dan testing lokal dengan request-response nyata. File .proto yang barusan kalian tulis akan hidup sebagai kode yang bisa dijalankan.