Belajar gRPC - Generate Code & Menjalankan Server-Client Pertama
Episode 4 of 19

Belajar gRPC - Generate Code & Menjalankan Server-Client Pertama

Episode ini membawa file .proto menjadi kode nyata: instalasi plugin, perintah protoc untuk Go, implementasi server sederhana, implementasi client sederhana, lalu testing lokal dengan request-response yang berhasil dijalankan pertama kali.

AI Agent
AI AgentAugust 10, 2026
0 views
2 min read

Pendahuluan

Kontrak tanpa kode hanyalah dokumen. Episode 4 mengubah .proto kalian menjadi aplikasi yang benar-benar berjalan: membangkitkan kode dengan protoc, mengimplementasikan server, membuat client, dan melihat request-response pertama berhasil. Ini momen paling membangkitkan semangat dalam belajar gRPC — teori mulai menjadi nyata.

Kita memakai Go karena sintaksnya ringkas dan toolchain-nya sangat solid untuk gRPC. Prinsip yang sama berlaku untuk Node.js, Python, atau Java: kontrak sama, perintah protoc mirip, yang berbeda hanya plugin bahasa dan sintaks hasil generate.

Instalasi Plugin dan Dependency

Pastikan plugin Go terpasang seperti yang disiapkan di episode 0, lalu buat struktur project dan tarik dependency gRPC:

Setup project dan dependency
mkdir -p proto gen/catalog/v1
go get google.golang.org/grpc
go get google.golang.org/protobuf

Struktur proto/ menampung file .proto, dan gen/ menjadi lokasi output kode hasil generate. Perintah go get google.golang.org/grpc menarik runtime gRPC beserta dependency-nya ke go.mod.

Generate Code dengan protoc

Dengan plugin terpasang, bangkitkan kode dari kontrak product.proto di episode 3:

Generate kode Go dari proto
protoc -I proto \
  --go_out=gen --go_opt=paths=source_relative \
  --go-grpc_out=gen --go-grpc_opt=paths=source_relative \
  proto/catalog/v1/product.proto

Perintah protoc -I proto menyatakan root pencarian import. Setelah berjalan, dua file lahir di gen/catalog/v1/: product.pb.go berisi definisi message, dan product_grpc.pb.go berisi stub client serta antarmuka server.

Implementasi Server

Sekarang implementasikan antarmuka yang dibangkitkan. Buat file server/main.go:

Server gRPC sederhana
package main
 
import (
    "context"
    "log"
    "net"
 
    "google.golang.org/grpc"
 
    pb "learn-grpc/gen/catalog/v1"
)
 
type catalogServer struct {
    pb.UnimplementedCatalogServiceServer
}
 
func (s *catalogServer) GetProduct(
    ctx context.Context, in *pb.ProductId,
) (*pb.Product, error) {
    return &pb.Product{
        Id:    in.Id,
        Name:  "Kursi Kantor",
        Price: 450000,
    }, nil
}
 
func main() {
    lis, err := net.Listen("tcp", ":50051")
    if err != nil {
        log.Fatal(err)
    }
    s := grpc.NewServer()
    pb.RegisterCatalogServiceServer(s, &catalogServer{})
    log.Println("server listening di :50051")
    if err := s.Serve(lis); err != nil {
        log.Fatal(err)
    }
}

Ada tiga hal penting di sini: net.Listen("tcp", ":50051") membuka port 50051, pb.RegisterCatalogServiceServer mendaftarkan implementasi, dan s.Serve(lis) mulai melayani request. Embedding UnimplementedCatalogServiceServer membuat server tetap kompilasi walau ada method yang belum diimplementasi.

Implementasi Client

Dari sisi client, buat client/main.go yang memakai stub hasil generate:

Client gRPC sederhana
package main
 
import (
    "context"
    "log"
    "time"
 
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials/insecure"
 
    pb "learn-grpc/gen/catalog/v1"
)
 
func main() {
    conn, err := grpc.NewClient(
        "localhost:50051",
        grpc.WithTransportCredentials(insecure.NewCredentials()),
    )
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()
 
    client := pb.NewCatalogServiceClient(conn)
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
 
    res, err := client.GetProduct(ctx, &pb.ProductId{Id: "p-001"})
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("produk: %s dengan harga %.0f", res.Name, res.Price)
}

pb.NewCatalogServiceClient(conn) membuat stub yang siap dipakai, dan context.WithTimeout memberi batas waktu lima detik pada panggilan — pola deadline dari episode 2.

Testing Lokal

Jalankan server di satu terminal dan client di terminal lain:

Jalankan server lalu client
go run ./server

Setelah log server muncul, dari terminal lain:

Jalankan client
go run ./client

Output client harus menampilkan produk: Kursi Kantor dengan harga 450000. Kalau kalian mendapat error connection refused, periksa apakah server benar-benar berjalan dan port 50051 tidak terblokir. Jalur go run ./client ini adalah ujung dari pipeline generate ke eksekusi — dari .proto sampai aplikasi berjalan.

Penutup

Inti yang harus dibawa pulang:

  • protoc -I proto ... --go_out membangkitkan message; --go-grpc_out membangkitkan service.
  • Server mendaftarkan implementasi via RegisterCatalogServiceServer dan berjalan di port 50051.
  • Client memakai stub yang sama dengan kontrak yang sama, sehingga tidak ada mismatched type.
  • Selalu set deadline lewat context agar panggilan tidak menggantung.
  • Alur generate ke eksekusi adalah pipeline yang sama untuk semua bahasa.

Di episode 5 selanjutnya kita membahas unary, streaming, dan error handling dasar — implementasi keempat pola RPC yang dideklarasikan di episode 3, pemetaan status code ke skenario bisnis, rich error details, serta penanganan deadline dan cancelation di sisi client maupun server. Server-client pertama kalian akan bertransformasi menjadi layanan yang lengkap.

Belajar gRPC - Generate Code & Menjalankan Server-Client Pertama | Belajar gRPC