Pada tahun-tahun belakangan ini, konsep Remote Procedure Call (RPC) kian populer dalam pengembangan backend services. Salah satu pattern yang paling sederhana tapi sering dipakai adalah Unary RPC, di mana klien mengirim satu permintaan dan server mengembalikan satu respons. Di artikel ini, saya akan membahas konsep Unary RPC dan bagaimana mengimplementasikannya menggunakan gRPC di lingkungan Go (Golang). Mari kita berangkat dari teori, praktik, dan best practice dunia nyata.
Apa itu Unary RPC?
Sebelum masuk ke kode, kita perlu memahami konsep dasarnya. Unary RPC adalah model komunikasi satu-ke-satu antara klien dan server:
- Single request –> Single response
Ilustrasi komunikasinya sangat mirip seperti fungsi biasa di dalam bahasa pemrograman, namun fungsi tersebut berjalan di server lain.
Alur Komunikasi Unary RPC
sequenceDiagram participant Client participant Server Client->>Server: Request (Data) Server-->>Client: Response (Data)
Studi Kasus: Service Pengelolaan Buku
Agar lebih nyata, kita akan buat simulasi sistem pengelolaan buku yang sederhana. Klien akan mengirim permintaan untuk mendapatkan informasi buku berdasarkan IDnya, dan server merespons dengan detail buku tersebut.
Membuat Definisi Protobuf
Kunci utama RPC di gRPC adalah file .proto yang mendefinisikan kontrak antar service.
// book.proto
syntax = "proto3";
package bookservice;
// Request
message GetBookRequest {
string id = 1;
}
// Response
message Book {
string id = 1;
string title = 2;
string author = 3;
int32 year = 4;
}
// Service
service BookService {
rpc GetBook (GetBookRequest) returns (Book);
}
Setelah membuat file ini, generate kode stub dengan perintah berikut:
protoc --go_out=. --go-grpc_out=. book.proto
Implementasi Server Unary RPC
Mari kita implementasikan service handler di Golang.
Struktur Dummy Database
// book_server.go
var books = map[string]*bookservice.Book{
"1": &bookservice.Book{Id: "1", Title: "Go Programming", Author: "John Doe", Year: 2021},
"2": &bookservice.Book{Id: "2", Title: "Distributed Systems", Author: "Jane Roe", Year: 2020},
}
Handler RPC - GetBook
type server struct {
bookservice.UnimplementedBookServiceServer
}
func (s *server) GetBook(
ctx context.Context,
req *bookservice.GetBookRequest,
) (*bookservice.Book, error) {
book, ok := books[req.Id]
if !ok {
return nil, status.Error(codes.NotFound, "book not found")
}
return book, nil
}
Main server
func main() {
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("Failed to listen: %v", err)
}
grpcServer := grpc.NewServer()
bookservice.RegisterBookServiceServer(grpcServer, &server{})
log.Println("Server running on port :50051")
if err := grpcServer.Serve(lis); err != nil {
log.Fatalf("Failed to serve: %v", err)
}
}
Implementasi Client Unary RPC
Mari simulasi klien yang melakukan request ke server menggunakan ID buku tertentu.
func main() {
conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
if err != nil {
log.Fatalf("Failed to connect: %v", err)
}
defer conn.Close()
client := bookservice.NewBookServiceClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
defer cancel()
bookID := "1"
res, err := client.GetBook(ctx, &bookservice.GetBookRequest{Id: bookID})
if err != nil {
log.Fatalf("Error: %v", err)
}
fmt.Printf("Book: %+v\n", res)
}
Simulasi: Request & Response
Mari kita lihat bagaimana komunikasi terjadi.
Langkah | Dari | Ke | Data |
---|---|---|---|
Mengirim permintaan buku | Client | Server | {id: "1"} |
Mencari buku | Server (db) | Internal | Lookup berdasarkan ID |
Mengirim respons | Server | Client | {id: "1", title: "Go Programming", ...} |
Alur Komunikasi Unggulan
Dengan unary RPC, alurnya simpel. Berikut diagram alur request-nya:
flowchart TD A[Client Kirim Request] --> B{Server Terima} B -- Buku Ada --> C[Server Kirim Data Buku] B -- Buku Tidak Ada --> D[Server Kirim Error] C & D --> E[Client Terima Respons]
Design ini sangat efisien untuk operasi yang memang hanya membutuhkan satu data dengan satu request.
Perbandingan dengan RPC Lain
Agar lebih jelas, berikut tabel perbandingan model komunikasi di gRPC:
Tipe RPC | Dari | Ke | Flow |
---|---|---|---|
Unary | Client | Server | Satu request, satu response |
Server Streaming | Client | Server | Satu request, stream response |
Client Streaming | Client | Server | Stream request, satu response |
Bidirectional Streaming | Client | Server | Stream request, stream response |
Manfaat dan Best Practice Unary RPC
Kelebihan
- Sederhana – Mirip pemakaian fungsi biasa.
- Cepat – Overhead sedikit, tidak ada stream.
- Cocok untuk operasi CRUD simple, auth, lookup data, dsb.
Best Practice
- Validasi Data — Validasi permintaan di server sebelum proses data.
- Timeout — Gunakan context timeout di client untuk menghindari hang.
- Error Handling — Kirim error message yang jelas dari server ke client.
- Versioning — Pertimbangkan versioning API sejak awal.
Kesimpulan
Unary RPC adalah pattern yang sangat powerful sekaligus sederhana untuk microservices. Di Go, dengan gRPC kita bisa mengimplementasikannya dengan sangat efisien dan maintainable. Pattern ini cocok untuk berbagai use case, terutama operasi pemanggilan remote yang satu-permintaan-satu-jawaban.
Selamat bereksperimen dengan unary RPC di service kamu! Jika kamu punya pertanyaan atau ingin berdiskusi lebih dalam, jangan ragu tinggalkan komentar di bawah.
12 Membuat Client gRPC Pertama Anda
Artikel Terhangat
13 Implementasi Unary RPC
06 Jun 2025
12 Membuat Client gRPC Pertama Anda
06 Jun 2025
11 Membuat Server gRPC Pertama Anda
06 Jun 2025
9 Meng-Generate Kode Go dari File Protobuf
06 Jun 2025
8 Memahami Sintaks Dasar File Protobuf
06 Jun 2025

13 Implementasi Unary RPC

12 Membuat Client gRPC Pertama Anda

11 Membuat Server gRPC Pertama Anda

9 Meng-Generate Kode Go dari File Protobuf
